Re: [PATCH] lib: Drop needless one line labels

2021-11-15 Thread Daniel Henrique Barboza




On 11/12/21 13:22, Michal Privoznik wrote:

In some cases we have a label that contains nothing but a return
statement. The amount of such labels rises as we use automagic
cleanup. Anyway, such labels are pointless and can be dropped.

Signed-off-by: Michal Privoznik 
---



Reviewed-by: Daniel Henrique Barboza 


  examples/c/domain/dommigrate.c   |  6 +-
  src/conf/domain_conf.c   | 70 +---
  src/conf/netdev_vport_profile_conf.c | 33 +-
  src/conf/storage_conf.c  | 12 ++--
  src/conf/storage_source_conf.c   | 15 ++---
  src/conf/virsavecookie.c |  3 +-
  src/hypervisor/virhostdev.c  |  4 +-
  src/libxl/libxl_migration.c  |  5 +-
  src/libxl/xen_xl.c   |  9 +--
  src/openvz/openvz_driver.c   |  5 +-
  src/qemu/qemu_capabilities.c |  5 +-
  src/qemu/qemu_monitor_json.c | 16 ++---
  src/qemu/qemu_snapshot.c | 21 +++---
  src/qemu/qemu_virtiofs.c | 22 +++
  src/rpc/virnetlibsshsession.c| 10 +--
  src/storage/storage_backend_iscsi.c  | 13 ++--
  src/test/test_driver.c   |  5 +-
  src/util/vircgroup.c |  4 +-
  src/util/vircgroupv1.c   | 24 +++
  src/util/virdnsmasq.c| 42 +---
  src/util/virhostcpu.c| 11 ++--
  tests/domainconftest.c   |  5 +-
  tests/qemuxml2argvtest.c | 11 +---
  tests/virpcitest.c   | 15 ++---
  tools/virsh-domain.c |  8 +--
  tools/virsh-host.c   |  6 +-
  tools/virsh-nodedev.c| 45 +
  tools/virsh-volume.c | 96 +++-
  28 files changed, 199 insertions(+), 322 deletions(-)

diff --git a/examples/c/domain/dommigrate.c b/examples/c/domain/dommigrate.c
index 3d32ada6d3..07a947e869 100644
--- a/examples/c/domain/dommigrate.c
+++ b/examples/c/domain/dommigrate.c
@@ -42,7 +42,7 @@ main(int argc, char *argv[])
  
  if (argc < 4) {

  usage(argv[0]);
-goto out;
+return EXIT_FAILURE;
  }
  
  src_uri = argv[1];

@@ -54,7 +54,7 @@ main(int argc, char *argv[])
  if (!conn) {
  fprintf(stderr, "No connection to the source hypervisor: %s.\n",
  virGetLastErrorMessage());
-goto out;
+return EXIT_FAILURE;
  }
  
  printf("Attempting to retrieve domain %s...\n", domname);

@@ -79,7 +79,5 @@ main(int argc, char *argv[])
  if (dom != NULL)
  virDomainFree(dom);
  virConnectClose(conn);
-
- out:
  return ret;
  }
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index da0c64b460..54218e76e7 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -18859,7 +18859,7 @@ virDomainDefParseIDs(virDomainDef *def,
  /* Extract domain name */
  if (!(def->name = virXPathString("string(./name[1])", ctxt))) {
  virReportError(VIR_ERR_NO_NAME, NULL);
-goto error;
+return -1;
  }
  
  /* Extract domain uuid. If both uuid and sysinfo/system/entry/uuid

@@ -18870,50 +18870,47 @@ virDomainDefParseIDs(virDomainDef *def,
  if (virUUIDGenerate(def->uuid) < 0) {
  virReportError(VIR_ERR_INTERNAL_ERROR,
 "%s", _("Failed to generate UUID"));
-goto error;
+return -1;
  }
  *uuid_generated = true;
  } else {
  if (virUUIDParse(tmp, def->uuid) < 0) {
  virReportError(VIR_ERR_INTERNAL_ERROR,
 "%s", _("malformed uuid element"));
-goto error;
+return -1;
  }
  VIR_FREE(tmp);
  }
  
  /* Extract domain genid - a genid can either be provided or generated */

  if ((n = virXPathNodeSet("./genid", ctxt, &nodes)) < 0)
-goto error;
+return -1;
  
  if (n > 0) {

  if (n != 1) {
  virReportError(VIR_ERR_XML_ERROR, "%s",
 _("element 'genid' can only appear once"));
-goto error;
+return -1;
  }
  def->genidRequested = true;
  if (!(tmp = virXPathString("string(./genid)", ctxt))) {
  if (virUUIDGenerate(def->genid) < 0) {
  virReportError(VIR_ERR_INTERNAL_ERROR,
 "%s", _("Failed to generate genid"));
-goto error;
+return -1;
  }
  def->genidGenerated = true;
  } else {
  if (virUUIDParse(tmp, def->genid) < 0) {
  virReportError(VIR_ERR_INTERNAL_ERROR,
 "%s", _("malformed genid element"));
- 

Re: [libvirt PATCH 13/13] ch_driver: emulator threadinfo & pinning callbacks

2021-11-12 Thread Daniel Henrique Barboza




On 10/21/21 16:31, Vineeth Pillai wrote:

From: Praveen K Paladugu 

Signed-off-by: Vineeth Pillai 
---
  src/ch/ch_driver.c | 154 +
  1 file changed, 154 insertions(+)

diff --git a/src/ch/ch_driver.c b/src/ch/ch_driver.c
index 97dfda85e1..786e2292a5 100644
--- a/src/ch/ch_driver.c
+++ b/src/ch/ch_driver.c
@@ -1321,6 +1321,158 @@ chDomainPinVcpu(virDomainPtr dom,
VIR_DOMAIN_AFFECT_LIVE);
  }
  
+

+
+static int
+chDomainGetEmulatorPinInfo(virDomainPtr dom,
+ unsigned char *cpumaps,
+ int maplen,
+ unsigned int flags)
+{
+virDomainObj *vm = NULL;
+virDomainDef *def;
+virCHDomainObjPrivate *priv;
+bool live;
+int ret = -1;
+virBitmap *cpumask = NULL;
+g_autoptr(virBitmap) bitmap = NULL;
+virBitmap *autoCpuset = NULL;
+
+virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
+  VIR_DOMAIN_AFFECT_CONFIG, -1);
+
+if (!(vm = chDomObjFromDomain(dom)))
+goto cleanup;
+
+if (virDomainGetEmulatorPinInfoEnsureACL(dom->conn, vm->def) < 0)
+goto cleanup;
+
+if (!(def = virDomainObjGetOneDefState(vm, flags, &live)))
+goto cleanup;
+
+if (live) {
+priv = vm->privateData;
+autoCpuset = priv->autoCpuset;
+}
+if (def->cputune.emulatorpin) {
+cpumask = def->cputune.emulatorpin;
+} else if (def->cpumask) {
+cpumask = def->cpumask;
+} else if (vm->def->placement_mode == VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO &&
+   autoCpuset) {
+cpumask = autoCpuset;
+} else {
+if (!(bitmap = virHostCPUGetAvailableCPUsBitmap()))
+goto cleanup;
+cpumask = bitmap;
+}
+
+virBitmapToDataBuf(cpumask, cpumaps, maplen);
+
+ret = 1;
+
+ cleanup:
+virDomainObjEndAPI(&vm);
+return ret;
+}
+
+static int
+chDomainPinEmulator(virDomainPtr dom,
+  unsigned char *cpumap,
+  int maplen,
+  unsigned int flags)
+{
+virCHDriver *driver = dom->conn->privateData;
+virDomainObj *vm;
+virCgroup *cgroup_emulator = NULL;
+virDomainDef *def;
+virDomainDef *persistentDef;
+int ret = -1;
+virCHDomainObjPrivate *priv;
+virBitmap *pcpumap = NULL;
+g_autoptr(virCHDriverConfig) cfg = NULL;
+g_autofree char *str = NULL;
+virTypedParameterPtr eventParams = NULL;
+int eventNparams = 0;
+int eventMaxparams = 0;
+
+virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
+  VIR_DOMAIN_AFFECT_CONFIG, -1);
+
+cfg = virCHDriverGetConfig(driver);
+
+if (!(vm = chDomObjFromDomain(dom)))
+goto cleanup;
+
+if (virDomainPinEmulatorEnsureACL(dom->conn, vm->def, flags) < 0)
+goto cleanup;
+
+if (virCHDomainObjBeginJob(vm, CH_JOB_MODIFY) < 0)
+goto cleanup;
+
+if (virDomainObjGetDefs(vm, flags, &def, &persistentDef) < 0)
+goto endjob;
+
+priv = vm->privateData;
+
+if (!(pcpumap = virBitmapNewData(cpumap, maplen)))
+goto endjob;
+
+if (virBitmapIsAllClear(pcpumap)) {
+virReportError(VIR_ERR_INVALID_ARG, "%s",
+   _("Empty cpu list for pinning"));
+goto endjob;
+}
+
+if (def) {
+if (virCgroupHasController(priv->cgroup, 
VIR_CGROUP_CONTROLLER_CPUSET)) {
+if (virCgroupNewThread(priv->cgroup, VIR_CGROUP_THREAD_EMULATOR,
+   0, false, &cgroup_emulator) < 0)
+goto endjob;
+
+if (chSetupCgroupCpusetCpus(cgroup_emulator, pcpumap) < 0) {
+virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+   _("failed to set cpuset.cpus in cgroup"
+ " for emulator threads"));
+goto endjob;
+}
+}
+
+if (virProcessSetAffinity(vm->pid, pcpumap, false) < 0)
+goto endjob;
+
+virBitmapFree(def->cputune.emulatorpin);
+def->cputune.emulatorpin = NULL;
+
+if (!(def->cputune.emulatorpin = virBitmapNewCopy(pcpumap)))
+goto endjob;
+
+if (virDomainObjSave(vm, driver->xmlopt, cfg->stateDir) < 0)
+goto endjob;
+
+str = virBitmapFormat(pcpumap);
+if (virTypedParamsAddString(&eventParams, &eventNparams,
+&eventMaxparams,
+VIR_DOMAIN_TUNABLE_CPU_EMULATORPIN,
+str) < 0)
+goto endjob;
+
+}
+
+
+ret = 0;
+
+endjob:


Wrong label indentation.


+virCHDomainObjEndJob(vm);
+
+cleanup:


Same here.


Thanks,


Daniel


+if (cgroup_emulator)
+virCgroupFree(cgroup_emulator);
+virBitmapFree(pcpumap);
+virDomainObjEndAPI(&vm);
+return ret;
+}
+
  #define CH_NB_NUMA_PARAM 2
  
  static int

@@ -1639,6 +1

Re: [libvirt PATCH 12/13] ch_process: Setup emulator and iothread settings

2021-11-12 Thread Daniel Henrique Barboza




On 10/21/21 16:31, Vineeth Pillai wrote:

From: Praveen K Paladugu 

using virCHProcessSetupPid

Signed-off-by: Praveen K Paladugu 
Signed-off-by: Vineeth Pillai 
---
  src/ch/ch_monitor.c | 60 ++
  src/ch/ch_monitor.h |  2 ++
  src/ch/ch_process.c | 78 +++--
  3 files changed, 138 insertions(+), 2 deletions(-)

diff --git a/src/ch/ch_monitor.c b/src/ch/ch_monitor.c
index 095779cb3f..924d510a2f 100644
--- a/src/ch/ch_monitor.c
+++ b/src/ch/ch_monitor.c
@@ -920,3 +920,63 @@ virCHMonitorResumeVM(virCHMonitor *mon)
  {
  return virCHMonitorPutNoContent(mon, URL_VM_RESUME);
  }
+
+/**
+ * virCHMonitorGetIOThreads:
+ * @mon: Pointer to the monitor
+ * @iothreads: Location to return array of IOThreadInfo data
+ *
+ * Retrieve the list of iothreads defined/running for the machine
+ *
+ * Returns count of IOThreadInfo structures on success
+ *-1 on error.
+ */
+int virCHMonitorGetIOThreads(virCHMonitor *mon,
+virDomainIOThreadInfo ***iothreads)
+{
+size_t nthreads = 0, niothreads = 0;
+int thd_index;
+virDomainIOThreadInfo **iothreadinfolist = NULL, *iothreadinfo = NULL;
+
+*iothreads = NULL;
+nthreads = virCHMonitorRefreshThreadInfo(mon);
+
+iothreadinfolist = g_new0(virDomainIOThreadInfo*, nthreads);
+
+for (thd_index = 0; thd_index < nthreads; thd_index++) {
+virBitmap *map = NULL;
+if (mon->threads[thd_index].type == virCHThreadTypeIO) {
+iothreadinfo = g_new0(virDomainIOThreadInfo, 1);
+
+iothreadinfo->iothread_id = mon->threads[thd_index].ioInfo.tid;
+
+if (!(map = virProcessGetAffinity(iothreadinfo->iothread_id)))
+goto cleanup;
+
+if (virBitmapToData(map, &(iothreadinfo->cpumap),
+&(iothreadinfo->cpumaplen)) < 0) {
+virBitmapFree(map);
+goto cleanup;
+}
+virBitmapFree(map);
+//Append to iothreadinfolist
+iothreadinfolist[niothreads] = iothreadinfo;
+niothreads++;
+}
+}
+VIR_DELETE_ELEMENT_INPLACE(iothreadinfolist,
+   niothreads, nthreads);
+*iothreads = iothreadinfolist;
+VIR_DEBUG("niothreads = %ld", niothreads);
+return niothreads;
+
+cleanup:
+if (iothreadinfolist) {
+for (thd_index = 0; thd_index < niothreads; thd_index++)
+VIR_FREE(iothreadinfolist[thd_index]);
+VIR_FREE(iothreadinfolist);
+}
+if (iothreadinfo)
+VIR_FREE(iothreadinfo);
+return -1;
+}
diff --git a/src/ch/ch_monitor.h b/src/ch/ch_monitor.h
index f8c3fa75e8..98edb0faf9 100644
--- a/src/ch/ch_monitor.h
+++ b/src/ch/ch_monitor.h
@@ -118,3 +118,5 @@ int virCHMonitorGetCPUInfo(virCHMonitor *mon,
 size_t maxvcpus);
  size_t virCHMonitorGetThreadInfo(virCHMonitor *mon, bool refresh,
   virCHMonitorThreadInfo **threads);
+int virCHMonitorGetIOThreads(virCHMonitor *mon,
+virDomainIOThreadInfo ***iothreads);
diff --git a/src/ch/ch_process.c b/src/ch/ch_process.c
index 8dce737adb..25c2910f9c 100644
--- a/src/ch/ch_process.c
+++ b/src/ch/ch_process.c
@@ -41,7 +41,6 @@ VIR_LOG_INIT("ch.ch_process");
  #define START_VM_POSTFIX ": starting up vm\n"
  
  
-

  static virCHMonitor *
  virCHProcessConnectMonitor(virCHDriver *driver,
 virDomainObj *vm)
@@ -131,7 +130,6 @@ virCHProcessUpdateInfo(virDomainObj *vm)
  virCHProcessUpdateConsole(vm, info);
  
  virJSONValueFree(info);

-
  return 0;
  }
  
@@ -313,6 +311,74 @@ virCHProcessSetupPid(virDomainObj *vm,

  return ret;
  }
  
+static int

+virCHProcessSetupIOThread(virDomainObj *vm,
+ virDomainIOThreadInfo *iothread)
+{
+virCHDomainObjPrivate *priv = vm->privateData;
+return virCHProcessSetupPid(vm, iothread->iothread_id,
+   VIR_CGROUP_THREAD_IOTHREAD,
+   iothread->iothread_id,
+   priv->autoCpuset, // This should be updated 
when CLH supports accepting
+ // iothread settings from input domain 
definition
+   vm->def->cputune.iothread_period,
+   vm->def->cputune.iothread_quota,
+   NULL); // CLH doesn't allow choosing a 
scheduler for iothreads.
+}
+
+static int
+virCHProcessSetupIOThreads(virDomainObj *vm)
+{
+virCHDomainObjPrivate *priv = vm->privateData;
+virDomainIOThreadInfo **iothreads = NULL;
+size_t i;
+size_t  niothreads;
+
+niothreads = virCHMonitorGetIOThreads(priv->monitor, &iothreads);
+for (i = 0; i < niothreads; i++) {
+VIR_DEBUG("IOThread index = %ld , tid = %d", i, 
iothreads[i]->iothread_id);
+if

Re: [libvirt PATCH 08/13] ch_cgroup: methods for cgroup mgmt in ch driver

2021-11-12 Thread Daniel Henrique Barboza




On 10/21/21 16:31, Vineeth Pillai wrote:

Signed-off-by: Vineeth Pillai 
Signed-off-by: Praveen K Paladugu 
---
  po/POTFILES.in  |   1 +
  src/ch/ch_cgroup.c  | 457 
  src/ch/ch_cgroup.h  |  45 +
  src/ch/ch_conf.c|   2 +
  src/ch/ch_conf.h|   4 +-
  src/ch/ch_domain.c  |  33 
  src/ch/ch_domain.h  |   3 +-
  src/ch/ch_monitor.c | 125 ++--
  src/ch/ch_monitor.h |  54 +-
  src/ch/ch_process.c | 288 +++-
  src/ch/ch_process.h |   3 +
  src/ch/meson.build  |   2 +
  12 files changed, 991 insertions(+), 26 deletions(-)
  create mode 100644 src/ch/ch_cgroup.c
  create mode 100644 src/ch/ch_cgroup.h

diff --git a/po/POTFILES.in b/po/POTFILES.in
index b554cf08ca..3a8db501bc 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -19,6 +19,7 @@
  @SRCDIR@src/bhyve/bhyve_parse_command.c
  @SRCDIR@src/bhyve/bhyve_process.c
  @SRCDIR@src/ch/ch_conf.c
+@SRCDIR@src/ch/ch_cgroup.c
  @SRCDIR@src/ch/ch_domain.c
  @SRCDIR@src/ch/ch_driver.c
  @SRCDIR@src/ch/ch_monitor.c
diff --git a/src/ch/ch_cgroup.c b/src/ch/ch_cgroup.c
new file mode 100644
index 00..6be2184cf1
--- /dev/null
+++ b/src/ch/ch_cgroup.c
@@ -0,0 +1,457 @@
+/*
+ * ch_cgroup.c: CH cgroup management
+ *
+ * Copyright Microsoft Corp. 2020-2021
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library.  If not, see
+ * .
+ */
+
+#include 
+
+#include "ch_cgroup.h"
+#include "ch_domain.h"
+#include "ch_process.h"
+#include "vircgroup.h"
+#include "virlog.h"
+#include "viralloc.h"
+#include "virerror.h"
+#include "domain_audit.h"
+#include "domain_cgroup.h"
+#include "virscsi.h"
+#include "virstring.h"
+#include "virfile.h"
+#include "virtypedparam.h"
+#include "virnuma.h"
+#include "virdevmapper.h"
+#include "virutil.h"
+
+#define VIR_FROM_THIS VIR_FROM_CH
+
+VIR_LOG_INIT("ch.ch_cgroup");
+
+static int
+chSetupBlkioCgroup(virDomainObj * vm)
+{
+virCHDomainObjPrivate *priv = vm->privateData;
+
+if (!virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_BLKIO)) {
+if (vm->def->blkio.weight || vm->def->blkio.ndevices) {
+virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+   _("Block I/O tuning is not available on this 
host"));
+return -1;
+} else {
+return 0;
+}
+}
+
+return virDomainCgroupSetupBlkio(priv->cgroup, vm->def->blkio);
+}
+
+
+static int
+chSetupMemoryCgroup(virDomainObj * vm)
+{
+virCHDomainObjPrivate *priv = vm->privateData;
+
+if (!virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_MEMORY)) {
+if (virMemoryLimitIsSet(vm->def->mem.hard_limit) ||
+virMemoryLimitIsSet(vm->def->mem.soft_limit) ||
+virMemoryLimitIsSet(vm->def->mem.swap_hard_limit)) {
+virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+   _("Memory cgroup is not available on this host"));
+return -1;
+} else {
+return 0;
+}
+}
+
+return virDomainCgroupSetupMemtune(priv->cgroup, vm->def->mem);
+}
+
+static int
+chSetupCpusetCgroup(virDomainObj * vm)
+{
+virCHDomainObjPrivate *priv = vm->privateData;
+
+if (!virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_CPUSET))
+return 0;
+
+if (virCgroupSetCpusetMemoryMigrate(priv->cgroup, true) < 0)
+return -1;
+
+return 0;
+}
+
+
+static int
+chSetupCpuCgroup(virDomainObj * vm)
+{
+virCHDomainObjPrivate *priv = vm->privateData;
+
+if (!virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_CPU)) {
+if (vm->def->cputune.sharesSpecified) {
+virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+   _("CPU tuning is not available on this host"));
+return -1;
+} else {
+return 0;
+}
+}
+
+if (vm->def->cputune.sharesSpecified) {
+
+if (virCgroupSetCpuShares(priv->cgroup, vm->def->cputune.shares) < 0)
+return -1;
+
+}
+
+return 0;
+}
+
+
+static int
+chInitCgroup(virDomainObj * vm, size_t nnicindexes, int *nicindexes)
+{
+virCHDomainObjPrivate *priv = vm->privateData;
+
+g_autoptr(virCHDriverConfig) cfg = virCHDriverGetConfig(priv->driver);
+
+if (!priv->driver->privileged)
+return 0;
+
+if (!virCgroupAvailable())
+return 0;
+

Re: [libvirt PATCH 06/13] ch_driver: domainGetVcpuPinInfo and nodeGetCPUMap

2021-11-12 Thread Daniel Henrique Barboza




On 10/21/21 16:31, Vineeth Pillai wrote:

Add domainGetVcpuPinInfo and nodeGetCPUMap callbacks to ch driver

Signed-off-by: Vineeth Pillai 
Signed-off-by: Praveen K Paladugu 
---
  src/ch/ch_domain.h | 12 +--
  src/ch/ch_driver.c | 54 ++
  2 files changed, 64 insertions(+), 2 deletions(-)

diff --git a/src/ch/ch_domain.h b/src/ch/ch_domain.h
index d9c9d34a19..e35777a9ec 100644
--- a/src/ch/ch_domain.h
+++ b/src/ch/ch_domain.h
@@ -23,6 +23,7 @@
  #include "ch_conf.h"
  #include "ch_monitor.h"
  #include "virchrdev.h"
+#include "vircgroup.h"
  
  /* Give up waiting for mutex after 30 seconds */

  #define CH_JOB_WAIT_TIME (1000ull * 30)
@@ -52,9 +53,16 @@ typedef struct _virCHDomainObjPrivate virCHDomainObjPrivate;
  struct _virCHDomainObjPrivate {
  struct virCHDomainJobObj job;
  
-virCHMonitor *monitor;

+virChrdevs *chrdevs;
+
+virCgroup *cgroup;
  
- virChrdevs *chrdevs;

+virCHDriver *driver;
+virCHMonitor *monitor;
+char *machineName;
+virBitmap *autoNodeset;
+virBitmap *autoCpuset;
+virChrdevs *devs;
  };
  
  #define CH_DOMAIN_PRIVATE(vm) \

diff --git a/src/ch/ch_driver.c b/src/ch/ch_driver.c
index 8ea5ce393d..62ca6c1994 100644
--- a/src/ch/ch_driver.c
+++ b/src/ch/ch_driver.c
@@ -990,6 +990,58 @@ chDomainGetMaxVcpus(virDomainPtr dom)
  return chDomainGetVcpusFlags(dom, (VIR_DOMAIN_AFFECT_LIVE | 
VIR_DOMAIN_VCPU_MAXIMUM));
  }
  
+static int

+chDomainGetVcpuPinInfo(virDomain *dom,
+   int ncpumaps,
+   unsigned char *cpumaps,
+   int maplen,
+   unsigned int flags)
+{
+virDomainObj *vm = NULL;
+virDomainDef *def;
+bool live;
+int ret = -1;
+g_autoptr(virBitmap) hostcpus = NULL;
+virBitmap *autoCpuset = NULL;
+
+virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
+  VIR_DOMAIN_AFFECT_CONFIG, -1);
+
+if (!(vm = chDomObjFromDomain(dom)))
+goto cleanup;
+
+if (virDomainGetVcpuPinInfoEnsureACL(dom->conn, vm->def) < 0)
+goto cleanup;
+
+if (!(def = virDomainObjGetOneDefState(vm, flags, &live)))
+goto cleanup;
+
+if (!(hostcpus = virHostCPUGetAvailableCPUsBitmap()))
+goto cleanup;
+
+if (live)
+autoCpuset = CH_DOMAIN_PRIVATE(vm)->autoCpuset;
+
+ret = virDomainDefGetVcpuPinInfoHelper(def, maplen, ncpumaps, cpumaps,
+   hostcpus, autoCpuset);
+cleanup:


Wrong label indentation. LGTM otherwise.


Daniel


+virDomainObjEndAPI(&vm);
+return ret;
+}
+
+static int
+chNodeGetCPUMap(virConnectPtr conn,
+  unsigned char **cpumap,
+  unsigned int *online,
+  unsigned int flags)
+{
+if (virNodeGetCPUMapEnsureACL(conn) < 0)
+return -1;
+
+return virHostCPUGetMap(cpumap, online, flags);
+}
+
+
  static int
  chDomainHelperGetVcpus(virDomainObj *vm,
 virVcpuInfoPtr info,
@@ -1126,6 +1178,8 @@ static virHypervisorDriver chHypervisorDriver = {
  .domainGetVcpus = chDomainGetVcpus, /* 7.9.0 */
  .domainGetVcpusFlags = chDomainGetVcpusFlags,   /* 7.9.0 */
  .domainGetMaxVcpus = chDomainGetMaxVcpus,   /* 7.9.0 */
+.domainGetVcpuPinInfo = chDomainGetVcpuPinInfo, /* 7.9.0 */
+.nodeGetCPUMap = chNodeGetCPUMap,   /* 7.9.0 */
  };
  
  static virConnectDriver chConnectDriver = {






Re: [libvirt PATCH 05/13] ch_driver, ch_domain: vcpu info getter callbacks

2021-11-12 Thread Daniel Henrique Barboza




On 10/21/21 16:31, Vineeth Pillai wrote:

Signed-off-by: Vineeth Pillai 
Signed-off-by: Praveen K Paladugu 
---
  src/ch/ch_domain.c |  25 
  src/ch/ch_domain.h |   4 ++
  src/ch/ch_driver.c | 138 +
  3 files changed, 167 insertions(+)

diff --git a/src/ch/ch_domain.c b/src/ch/ch_domain.c
index fedde4581b..c0b0b1005a 100644
--- a/src/ch/ch_domain.c
+++ b/src/ch/ch_domain.c
@@ -338,3 +338,28 @@ virCHDomainGetMonitor(virDomainObj *vm)
  {
  return CH_DOMAIN_PRIVATE(vm)->monitor;
  }
+
+pid_t
+virCHDomainGetVcpuPid(virDomainObj *vm,
+ unsigned int vcpuid)
+{
+virDomainVcpuDef *vcpu = virDomainDefGetVcpu(vm->def, vcpuid);
+return CH_DOMAIN_VCPU_PRIVATE(vcpu)->tid;
+}
+
+bool
+virCHDomainHasVcpuPids(virDomainObj *vm)
+{
+size_t i;
+size_t maxvcpus = virDomainDefGetVcpusMax(vm->def);
+virDomainVcpuDef *vcpu;
+
+for (i = 0; i < maxvcpus; i++) {
+vcpu = virDomainDefGetVcpu(vm->def, i);
+
+if (CH_DOMAIN_VCPU_PRIVATE(vcpu)->tid > 0)
+return true;
+}
+
+return false;
+}
diff --git a/src/ch/ch_domain.h b/src/ch/ch_domain.h
index 75b9933130..d9c9d34a19 100644
--- a/src/ch/ch_domain.h
+++ b/src/ch/ch_domain.h
@@ -82,3 +82,7 @@ virCHDomainObjBeginJob(virDomainObj *obj, enum virCHDomainJob 
job)
  
  void

  virCHDomainObjEndJob(virDomainObj *obj);
+
+int virCHDomainRefreshVcpuInfo(virDomainObj *vm);
+pid_t virCHDomainGetVcpuPid(virDomainObj *vm, unsigned int vcpuid);
+bool virCHDomainHasVcpuPids(virDomainObj *vm);
diff --git a/src/ch/ch_driver.c b/src/ch/ch_driver.c
index 1824d2fd16..8ea5ce393d 100644
--- a/src/ch/ch_driver.c
+++ b/src/ch/ch_driver.c
@@ -952,6 +952,141 @@ static int chStateInitialize(bool privileged,
  return ret;
  }
  
+static int

+chDomainGetVcpusFlags(virDomainPtr dom, unsigned int flags)
+{
+virDomainObj *vm;
+virDomainDef *def;
+int ret = -1;
+
+virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
+  VIR_DOMAIN_AFFECT_CONFIG |
+  VIR_DOMAIN_VCPU_MAXIMUM |
+  VIR_DOMAIN_VCPU_GUEST, -1);
+
+if (!(vm = chDomObjFromDomain(dom)))
+return -1;
+
+if (virDomainGetVcpusFlagsEnsureACL(dom->conn, vm->def, flags) < 0)
+goto cleanup;
+
+if (!(def = virDomainObjGetOneDef(vm, flags)))
+goto cleanup;
+
+if (flags & VIR_DOMAIN_VCPU_MAXIMUM)
+ret = virDomainDefGetVcpusMax(def);
+else
+ret = virDomainDefGetVcpus(def);
+
+
+cleanup:


Label indentation in this case is one space only, without changing the
indentation level of the code that follows it. See docs/coding-style.rst
for an example. chStateInitialize() in ch_driver.c has another example
as well:

---

 cleanup:
if (ret != VIR_DRV_STATE_INIT_COMPLETE)
chStateCleanup();
return ret;
}

---


+virDomainObjEndAPI(&vm);
+return ret;
+}
+
+static int
+chDomainGetMaxVcpus(virDomainPtr dom)
+{
+return chDomainGetVcpusFlags(dom, (VIR_DOMAIN_AFFECT_LIVE | 
VIR_DOMAIN_VCPU_MAXIMUM));
+}
+
+static int
+chDomainHelperGetVcpus(virDomainObj *vm,
+   virVcpuInfoPtr info,
+   unsigned long long *cpuwait,
+   int maxinfo,
+   unsigned char *cpumaps,
+   int maplen)
+{
+size_t ncpuinfo = 0;
+size_t i;
+
+if (maxinfo == 0)
+return 0;
+
+if (!virCHDomainHasVcpuPids(vm)) {
+virReportError(VIR_ERR_OPERATION_INVALID,
+   "%s", _("cpu affinity is not supported"));
+return -1;
+}
+
+if (info)
+memset(info, 0, sizeof(*info) * maxinfo);
+
+if (cpumaps)
+memset(cpumaps, 0, sizeof(*cpumaps) * maxinfo);
+
+for (i = 0; i < virDomainDefGetVcpusMax(vm->def) && ncpuinfo < maxinfo; 
i++) {
+virDomainVcpuDef *vcpu = virDomainDefGetVcpu(vm->def, i);
+pid_t vcpupid = virCHDomainGetVcpuPid(vm, i);
+virVcpuInfoPtr vcpuinfo = info + ncpuinfo;
+
+if (!vcpu->online)
+continue;
+
+if (info) {
+vcpuinfo->number = i;
+vcpuinfo->state = VIR_VCPU_RUNNING;
+if (virProcessGetStatInfo(&vcpuinfo->cpuTime,
+  &vcpuinfo->cpu, NULL,
+  vm->pid, vcpupid) < 0) {
+virReportSystemError(errno, "%s",
+ _("cannot get vCPU placement & pCPU 
time"));
+return -1;
+}
+}
+
+if (cpumaps) {
+unsigned char *cpumap = VIR_GET_CPUMAP(cpumaps, maplen, ncpuinfo);
+virBitmap *map = NULL;
+
+if (!(map = virProcessGetAffinity(vcpupid)))
+return -1;
+
+virBitmapToDataBuf(map, cpumap, maplen);
+virBitmapFree(map);
+}
+
+if (cpuwait) {
+if (virProcessGetSchedInfo(&(cpuwait[ncpuinfo]), vm->pid, vcpupid) 
< 0)
+

Re: [libvirt PATCH 01/13] util: Helper functions to get process info

2021-11-12 Thread Daniel Henrique Barboza




On 10/21/21 16:31, Vineeth Pillai wrote:

These helper methods are used to capture vcpu information
in ch driver.

Signed-off-by: Vineeth Pillai 
Signed-off-by: Praveen K Paladugu 
---
  src/util/virprocess.c | 136 ++
  src/util/virprocess.h |   5 ++
  2 files changed, 141 insertions(+)

diff --git a/src/util/virprocess.c b/src/util/virprocess.c
index 6de3f36f52..0164d70df6 100644
--- a/src/util/virprocess.c
+++ b/src/util/virprocess.c
@@ -1721,3 +1721,139 @@ virProcessSetScheduler(pid_t pid G_GNUC_UNUSED,
  }
  
  #endif /* !WITH_SCHED_SETSCHEDULER */

+
+/*
+TODO: This method was cloned from qemuGetProcessInfo in src/qemu/qemu_driver.c.
+Need to refactor qemu driver to use this shared function.
+*/


Instead of cloning and leaving a TODO just go ahead and do the change in the
qemu_driver.c as well.

You don't need to change every instance of qemuGetProcessInfo in QEMU files
to use this new helper. Just change qemuGetProcessInfo to use
virProcessGetStatInfo:


static int
qemuGetProcessInfo(unsigned long long *cpuTime, int *lastCpu, long *vm_rss,
   pid_t pid, int tid)
{
return virProcessGetStatInfo(cpuTime, lastCpu, vm_rss, pid, tid);
}


Same thing down below with qemuGetSchedInfo and virProcessGetSchedInfo.


Thanks,


Daniel



+int
+virProcessGetStatInfo(unsigned long long *cpuTime, int *lastCpu, long *vm_rss,
+   pid_t pid, pid_t tid)
+{
+g_autofree char *proc = NULL;
+FILE *pidinfo;
+unsigned long long usertime = 0, systime = 0;
+long rss = 0;
+int cpu = 0;
+
+/* In general, we cannot assume pid_t fits in int; but /proc parsing
+ * is specific to Linux where int works fine.  */
+if (tid)
+proc = g_strdup_printf("/proc/%d/task/%d/stat", (int)pid, tid);
+else
+proc = g_strdup_printf("/proc/%d/stat", (int)pid);
+if (!proc)
+return -1;
+
+pidinfo = fopen(proc, "r");
+
+/* See 'man proc' for information about what all these fields are. We're
+ * only interested in a very few of them */
+if (!pidinfo ||
+fscanf(pidinfo,
+   /* pid -> stime */
+   "%*d (%*[^)]) %*c %*d %*d %*d %*d %*d %*u %*u %*u %*u %*u %llu 
%llu"
+   /* cutime -> endcode */
+   "%*d %*d %*d %*d %*d %*d %*u %*u %ld %*u %*u %*u"
+   /* startstack -> processor */
+   "%*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*d %d",
+   &usertime, &systime, &rss, &cpu) != 4) {
+VIR_WARN("cannot parse process status data");
+}
+
+/* We got jiffies
+ * We want nanoseconds
+ * _SC_CLK_TCK is jiffies per second
+ * So calculate thus
+ */
+if (cpuTime)
+*cpuTime = 1000ull * 1000ull * 1000ull * (usertime + systime)
+/ (unsigned long long)sysconf(_SC_CLK_TCK);
+if (lastCpu)
+*lastCpu = cpu;
+
+if (vm_rss)
+*vm_rss = rss * virGetSystemPageSizeKB();
+
+
+VIR_DEBUG("Got status for %d/%d user=%llu sys=%llu cpu=%d rss=%ld",
+  (int)pid, tid, usertime, systime, cpu, rss);
+
+VIR_FORCE_FCLOSE(pidinfo);
+
+return 0;
+}
+/*
+TODO: This method was cloned from qemuGetSchedInfo in src/qemu/qemu_driver.c.
+Need to refactor qemu driver to use this shared function.
+*/
+int virProcessGetSchedInfo(unsigned long long *cpuWait, pid_t pid, pid_t tid)
+{
+g_autofree char *proc = NULL;
+g_autofree char *data = NULL;
+char **lines = NULL;
+size_t i;
+int ret = -1;
+double val;
+
+*cpuWait = 0;
+
+/* In general, we cannot assume pid_t fits in int; but /proc parsing
+ * is specific to Linux where int works fine.  */
+if (tid)
+proc = g_strdup_printf("/proc/%d/task/%d/sched", (int)pid, (int)tid);
+else
+proc = g_strdup_printf("/proc/%d/sched", (int)pid);
+if (!proc)
+goto cleanup;
+ret = -1;
+
+/* The file is not guaranteed to exist (needs CONFIG_SCHED_DEBUG) */
+if (access(proc, R_OK) < 0) {
+ret = 0;
+goto cleanup;
+}
+
+if (virFileReadAll(proc, (1<<16), &data) < 0)
+goto cleanup;
+
+lines = g_strsplit(data, "\n", 0);
+if (!lines)
+goto cleanup;
+
+for (i = 0; lines[i] != NULL; i++) {
+const char *line = lines[i];
+
+/* Needs CONFIG_SCHEDSTATS. The second check
+ * is the old name the kernel used in past */
+if (STRPREFIX(line, "se.statistics.wait_sum") ||
+STRPREFIX(line, "se.wait_sum")) {
+line = strchr(line, ':');
+if (!line) {
+virReportError(VIR_ERR_INTERNAL_ERROR,
+   _("Missing separator in sched info '%s'"),
+   lines[i]);
+goto cleanup;
+}
+line++;
+while (*line == ' ')
+line++;
+
+if (virStrToDouble(line, NULL, &val) < 0) {
+virReportError(VIR_ERR_INTERNAL_E

[PATCH 1/1] NEWS: document DEVICE_UNPLUG_GUEST_ERROR support

2021-11-12 Thread Daniel Henrique Barboza
Signed-off-by: Daniel Henrique Barboza 
---
 NEWS.rst | 5 +
 1 file changed, 5 insertions(+)

diff --git a/NEWS.rst b/NEWS.rst
index a71b84c363..9e990ff93a 100644
--- a/NEWS.rst
+++ b/NEWS.rst
@@ -30,6 +30,11 @@ v7.10.0 (unreleased)
 Libvirt is now able to report interface information from the guest's
 perspective (using guest agent).
 
+  * qemu: detect guest side errors during device removal
+
+Libvirt is now able to detect guest side errors during device removal by
+using the DEVICE_UNPLUG_GUEST_ERROR event, available in QEMU 6.2.0.
+
 * **Bug fixes**
 
 
-- 
2.31.1



Re: [PATCH 0/2] DEVICE_UNPLUG_GUEST_ERROR support

2021-11-12 Thread Daniel Henrique Barboza




On 11/12/21 09:13, Michal Prívozník wrote:

On 11/1/21 1:27 AM, Daniel Henrique Barboza wrote:

Hi,

This small series adds support to a new QMP event called
DEVICE_UNPLUG_GUEST_SUPPORT introduced recently in upstream QEMU.
This event is emitted when a device removal error is detected in the guest
side. Libvirt can use this event to to abort the removal operation
immediately instead of waiting for the operation to timeout.

Upstream QEMU is emitting this event in the following cases:

- memory removal errors in ACPI and pseries guests
- CPU removal errors in pseries guests

Adding support to DEVICE_UNPLUG_GUEST_ERROR will allow Libvirt to
detect all device removal errors that QEMU might add in the future.

The patches were tested using a common scenario where CPU removal will
fail everytime in a pseries guest:

- start a pseries guest with 1 CPU
- add one CPU
- offline vcpu0 in the guest kernel
- try to remove the recently added CPU (vcpu1). The kernel will refuse the
unplug because vcpu1 is the last online CPU

This test case will cause 'setvcpus' to hang until the timeout is fired:

[danielhb@ltc-boston118 build]$ sudo ./run tools/virsh setvcpus f34 1
error: Timed out during operation: vcpu unplug request timed out. Unplug result 
must be manually inspected in the domain

With this series applied, 'setvcpus' will report the error as soon as
the DEVICE_UNPLUG_GUEST_ERROR event is received:

[danielhb@ltc-boston118 build]$ sudo ./run tools/virsh setvcpus f34 1
error: operation failed: unplug of device was rejected by the guest


I haven't add any documentation because I didn't find a good place to
document this change, and I'm not sure if this is necessary either since
this doesn't change user ABI. If this requires a doc change please let
me know.


Right, this is an internal implementation and your patches just emit an
already existing event, so I think no additional doc is needed. Except
maybe a NEWS.rst?


Yeah, perhaps a NEWS.rst entry is warranted in the "Improvements" section.
I'll send a patch.








Daniel Henrique Barboza (2):
   tests: update QEMU and domain ppc64 capabilities for qemu 6.2
   qemu: add DEVICE_UNPLUG_GUEST_ERROR event support

  src/qemu/qemu_monitor.c   |12 +
  src/qemu/qemu_monitor.h   | 9 +
  src/qemu/qemu_monitor_json.c  |19 +
  src/qemu/qemu_process.c   |37 +
  tests/domaincapsdata/qemu_6.2.0.ppc64.xml |   138 +
  .../caps_6.2.0.ppc64.replies  | 31062 
  .../qemucapabilitiesdata/caps_6.2.0.ppc64.xml |  1167 +
  ...default-video-type-ppc64.ppc64-latest.args |13 +-
  ...ault-cpu-kvm-pseries-2.7.ppc64-latest.args |13 +-
  ...ault-cpu-kvm-pseries-3.1.ppc64-latest.args |13 +-
  ...ault-cpu-kvm-pseries-4.2.ppc64-latest.args |13 +-
  ...ault-cpu-tcg-pseries-2.7.ppc64-latest.args |13 +-
  ...ault-cpu-tcg-pseries-3.1.ppc64-latest.args |13 +-
  ...ault-cpu-tcg-pseries-4.2.ppc64-latest.args |13 +-
  .../ppc64-pseries-graphics.ppc64-latest.args  |29 +-
  .../ppc64-pseries-headless.ppc64-latest.args  |23 +-
  .../ppc64-tpmproxy-single.ppc64-latest.args   |11 +-
  .../ppc64-tpmproxy-with-tpm.ppc64-latest.args |13 +-
  .../tpm-emulator-spapr.ppc64-latest.args  |19 +-
  19 files changed, 32531 insertions(+), 99 deletions(-)
  create mode 100644 tests/domaincapsdata/qemu_6.2.0.ppc64.xml
  create mode 100644 tests/qemucapabilitiesdata/caps_6.2.0.ppc64.replies
  create mode 100644 tests/qemucapabilitiesdata/caps_6.2.0.ppc64.xml

/>>


Reviewed-by: Michal Privoznik 


Pushed. Thanks!

Daniel


Michal





Re: [libvirt PATCH v2 0/3] PCI VPD: Handle More Edge Cases

2021-10-31 Thread Daniel Henrique Barboza




On 10/29/21 15:57, Dmitrii Shcherbakov wrote:

This patch set improves edge case testing:

* The parser is now more strict about checking boundary conditions when
   parsing fields: an invalid field length is a possibility which is
now being accounted for;
* The parser will now make sure that RV and RW fields are the last
   in their section by making sure that no more data is left to read
after those;
* The RW field in the read-write section is not considered a VPD format
   violation even though it is a violation of the spec since it does not
   prevent Libvirt from parsing valid data for presenting it to a user.
   This is a policy decision made by Libvirt in favor of usability with
   hardware that does not strictly follow the PCI/PCIe VPD spec.



Libvirtd in a Power9 host is throwing these warnings on every startup:


Running 'src/libvirtd'...
2021-10-31 23:56:40.637+: 140468: info : libvirt version: 7.9.0
2021-10-31 23:56:40.637+: 140468: info : hostname: ltc-boston118
2021-10-31 23:56:40.804+: 140520: error : 
virPCIVPDParseVPDLargeResourceFields:588 : internal error: VPD-W does not 
contain the mandatory RW field
2021-10-31 23:56:40.808+: 140520: error : 
virPCIVPDParseVPDLargeResourceFields:588 : internal error: VPD-W does not 
contain the mandatory RW field
2021-10-31 23:56:40.813+: 140520: error : 
virPCIVPDParseVPDLargeResourceFields:588 : internal error: VPD-W does not 
contain the mandatory RW field
2021-10-31 23:56:40.817+: 140520: error : 
virPCIVPDParseVPDLargeResourceFields:588 : internal error: VPD-W does not 
contain the mandatory RW field


With this series the warnings are now gone.


All patches:

Tested-by: Daniel Henrique Barboza 






Invalid field values are now skipped instead of halting further parsing
completely.

Some vendors use 0xFF as placeholders in VPD-W since those values do not
correspond to printable ASCII characters, they will be discarded,
however, parsing will continue beyond that point.

Also, it turns out that some vendors use printable ASCII characters not
present in the alphanumeric range. Following a mailing list discussion
Libvirt will accept printable ASCII characters to avoid cases where
useful data is discarded.

https://listman.redhat.com/archives/libvir-list/2021-October/msg01043.html

Higher-level software needs to account for this character set and act
accordingly.

For example, the outcome of this is that one may get "N/A" as a value
for a serial number that is supposed to be unique, however, there is
no way for Libvirt to validate serial number uniqueness anyway even if
it was a different character sequence.

https://gitlab.com/dmitriis/libvirt/-/pipelines/398517951
(x86_64 only, have not set up arch-specific runners yet and over the
limit of what gitlab provides)

Dmitrii Shcherbakov (3):
   PCI VPD: handle additional edge cases
   PCI VPD: Skip fields with invalid values
   PCI VPD: Fix a wrong return code in a test case

  src/util/virpcivpd.c  |  63 +++---
  tests/virpcivpdtest.c | 263 --
  2 files changed, 296 insertions(+), 30 deletions(-)





[PATCH 2/2] qemu: add DEVICE_UNPLUG_GUEST_ERROR event support

2021-10-31 Thread Daniel Henrique Barboza
The upcoming QEMU 6.2.0 implements a new event called
DEVICE_UNPLUG_GUEST_ERROR, a new event that reports generic device
unplug errors that were detected by the guest and reported back to QEMU.

This new event is going to be specially useful for pseries guests that
uses newer kernels (must have kernel commit 29c9a2699e71), which is the
case for Fedora 34 at this moment. These guests have the capability of
reporting CPU removal errors back to QEMU which, starting in 6.2.0, will
emit the DEVICE_UNPLUG_GUEST_ERROR event. Libvirt can use this event to
abort the device removal immediately instead of waiting for 'setvcpus'
timeout.

QEMU 6.2.0 is also going to emit DEVICE_UNPLUG_GUEST_ERROR for memory
hotunplug errors, both in pseries and ACPI guests. QEMU 6.1.0 reports
memory removal errors using the MEM_UNPLUG_ERROR event, which is going to
be deprecated by DEVICE_UNPLUG_GUEST_ERROR in 6.2.0. Given that
Libvirt wasn't handling the MEM_UNPLUG_ERROR event we don't need to
worry about it - adding support to DEVICE_UNPLUG_GUEST_ERROR will be
enough to cover all future cases.

This patch adds support to DEVICE_UNPLUG_GUEST_ERROR by adding the
minimal wiring required for Libvirt to be aware of it. The monitor
callback for this event will abort the pending removal operation of the
device reported by the "device" property of the event. Most of the heavy
lifting is already done by existing code that handles
QEMU_DOMAIN_UNPLUGGING_DEVICE_STATUS_GUEST_REJECTED, making our life
easier to abort the pending removal operation.

Signed-off-by: Daniel Henrique Barboza 
---
 src/qemu/qemu_monitor.c  | 12 
 src/qemu/qemu_monitor.h  |  9 +
 src/qemu/qemu_monitor_json.c | 19 ++
 src/qemu/qemu_process.c  | 37 
 4 files changed, 77 insertions(+)

diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index 908ee0d302..abfc8c62ca 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -1353,6 +1353,18 @@ qemuMonitorEmitDeviceDeleted(qemuMonitor *mon,
 }
 
 
+void
+qemuMonitorEmitDeviceUnplugErr(qemuMonitor *mon,
+   const char *devPath,
+   const char *devAlias)
+{
+VIR_DEBUG("mon=%p", mon);
+
+QEMU_MONITOR_CALLBACK(mon, domainDeviceUnplugError, mon->vm,
+  devPath, devAlias);
+}
+
+
 void
 qemuMonitorEmitNicRxFilterChanged(qemuMonitor *mon,
   const char *devAlias)
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index b54c1cf87a..ba529c5241 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -294,6 +294,11 @@ typedef void 
(*qemuMonitorDomainDeviceDeletedCallback)(qemuMonitor *mon,
virDomainObj *vm,
const char *devAlias,
void *opaque);
+typedef void (*qemuMonitorDomainDeviceUnplugErrCallback)(qemuMonitor *mon,
+ virDomainObj *vm,
+ const char *devPath,
+ const char *devAlias,
+ void *opaque);
 typedef void (*qemuMonitorDomainNicRxFilterChangedCallback)(qemuMonitor *mon,
 virDomainObj *vm,
 const char 
*devAlias,
@@ -454,6 +459,7 @@ struct _qemuMonitorCallbacks {
 qemuMonitorDomainGuestCrashloadedCallback domainGuestCrashloaded;
 qemuMonitorDomainMemoryFailureCallback domainMemoryFailure;
 qemuMonitorDomainMemoryDeviceSizeChange domainMemoryDeviceSizeChange;
+qemuMonitorDomainDeviceUnplugErrCallback domainDeviceUnplugError;
 };
 
 qemuMonitor *qemuMonitorOpen(virDomainObj *vm,
@@ -542,6 +548,9 @@ void qemuMonitorEmitGuestPanic(qemuMonitor *mon,
qemuMonitorEventPanicInfo *info);
 void qemuMonitorEmitDeviceDeleted(qemuMonitor *mon,
   const char *devAlias);
+void qemuMonitorEmitDeviceUnplugErr(qemuMonitor *mon,
+const char *devPath,
+const char *devAlias);
 void qemuMonitorEmitNicRxFilterChanged(qemuMonitor *mon,
const char *devAlias);
 void qemuMonitorEmitSerialChange(qemuMonitor *mon,
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index e9be9bdabd..065ba0dc39 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -113,6 +113,7 @@ static void 
qemuMonitorJSONHandlePRManagerStatusChanged(qemuMonitor *mon, virJSO
 static void qemuMonitorJSONHandleRdmaGidStatusChanged(qemuMonit

[PATCH 0/2] DEVICE_UNPLUG_GUEST_ERROR support

2021-10-31 Thread Daniel Henrique Barboza
Hi,

This small series adds support to a new QMP event called
DEVICE_UNPLUG_GUEST_SUPPORT introduced recently in upstream QEMU.
This event is emitted when a device removal error is detected in the guest
side. Libvirt can use this event to to abort the removal operation
immediately instead of waiting for the operation to timeout.

Upstream QEMU is emitting this event in the following cases:

- memory removal errors in ACPI and pseries guests
- CPU removal errors in pseries guests

Adding support to DEVICE_UNPLUG_GUEST_ERROR will allow Libvirt to
detect all device removal errors that QEMU might add in the future.

The patches were tested using a common scenario where CPU removal will
fail everytime in a pseries guest:

- start a pseries guest with 1 CPU
- add one CPU
- offline vcpu0 in the guest kernel
- try to remove the recently added CPU (vcpu1). The kernel will refuse the
unplug because vcpu1 is the last online CPU

This test case will cause 'setvcpus' to hang until the timeout is fired:

[danielhb@ltc-boston118 build]$ sudo ./run tools/virsh setvcpus f34 1
error: Timed out during operation: vcpu unplug request timed out. Unplug result 
must be manually inspected in the domain

With this series applied, 'setvcpus' will report the error as soon as
the DEVICE_UNPLUG_GUEST_ERROR event is received:

[danielhb@ltc-boston118 build]$ sudo ./run tools/virsh setvcpus f34 1
error: operation failed: unplug of device was rejected by the guest 
 


I haven't add any documentation because I didn't find a good place to
document this change, and I'm not sure if this is necessary either since
this doesn't change user ABI. If this requires a doc change please let
me know.



Daniel Henrique Barboza (2):
  tests: update QEMU and domain ppc64 capabilities for qemu 6.2
  qemu: add DEVICE_UNPLUG_GUEST_ERROR event support

 src/qemu/qemu_monitor.c   |12 +
 src/qemu/qemu_monitor.h   | 9 +
 src/qemu/qemu_monitor_json.c  |19 +
 src/qemu/qemu_process.c   |37 +
 tests/domaincapsdata/qemu_6.2.0.ppc64.xml |   138 +
 .../caps_6.2.0.ppc64.replies  | 31062 
 .../qemucapabilitiesdata/caps_6.2.0.ppc64.xml |  1167 +
 ...default-video-type-ppc64.ppc64-latest.args |13 +-
 ...ault-cpu-kvm-pseries-2.7.ppc64-latest.args |13 +-
 ...ault-cpu-kvm-pseries-3.1.ppc64-latest.args |13 +-
 ...ault-cpu-kvm-pseries-4.2.ppc64-latest.args |13 +-
 ...ault-cpu-tcg-pseries-2.7.ppc64-latest.args |13 +-
 ...ault-cpu-tcg-pseries-3.1.ppc64-latest.args |13 +-
 ...ault-cpu-tcg-pseries-4.2.ppc64-latest.args |13 +-
 .../ppc64-pseries-graphics.ppc64-latest.args  |29 +-
 .../ppc64-pseries-headless.ppc64-latest.args  |23 +-
 .../ppc64-tpmproxy-single.ppc64-latest.args   |11 +-
 .../ppc64-tpmproxy-with-tpm.ppc64-latest.args |13 +-
 .../tpm-emulator-spapr.ppc64-latest.args  |19 +-
 19 files changed, 32531 insertions(+), 99 deletions(-)
 create mode 100644 tests/domaincapsdata/qemu_6.2.0.ppc64.xml
 create mode 100644 tests/qemucapabilitiesdata/caps_6.2.0.ppc64.replies
 create mode 100644 tests/qemucapabilitiesdata/caps_6.2.0.ppc64.xml

-- 
2.31.1



Re: [PATCH] virresctrl: Fix updating the mask for a cache resource

2021-07-07 Thread Daniel Henrique Barboza




On 7/2/21 4:23 AM, Vinayak Kale wrote:

In 'virResctrlAllocUpdateMask', mask is updated only if 'previous mask' is NULL.

By default, the bitmask for a cache resource for a VM is initialized with
'default-resctrl-group' bitmask. So the 'previous mask' would not be NULL and
mask won't get updated if cachetune is configured for a VM. This causes libvirt
to use same bitmask as 'default-resctrl-group' bitmask for a cache resource for
a VM. This patch fixes the issue.

Fixes: d8a354954aba9cd45ab0317915a0a2be27c04767

Signed-off-by: Vinayak Kale 
---


I was going to suggest whether cachetune couldn't just overwrite the default
mask if it's configured, but that would just shift the problem somewhere else.

This fix seems adequate.

Reviewed-by: Daniel Henrique Barboza 




  src/util/virresctrl.c | 6 --
  1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/src/util/virresctrl.c b/src/util/virresctrl.c
index 35e92022db..a7d36f492c 100644
--- a/src/util/virresctrl.c
+++ b/src/util/virresctrl.c
@@ -1104,8 +1104,10 @@ virResctrlAllocUpdateMask(virResctrlAlloc *alloc,
  VIR_EXPAND_N(a_type->masks, a_type->nmasks,
   cache - a_type->nmasks + 1);
  
-if (!a_type->masks[cache])

-a_type->masks[cache] = virBitmapNewCopy(mask);
+if (a_type->masks[cache])
+virBitmapFree(a_type->masks[cache]);
+
+a_type->masks[cache] = virBitmapNewCopy(mask);
  
  return 0;

  }





Re: [PATCH] qemu: Don't use memory-backend-memfd for NVDIMMs

2021-07-07 Thread Daniel Henrique Barboza




On 6/22/21 4:11 AM, Michal Privoznik wrote:

If guest is configured to use memfd then the function that build
memory-backend-* part of command line will put
memory-backend-memfd, always. Even for NVDIMMs. This is not
correct, because NVDIMMs need a backing path (usually to a real
host NVDIMM device). Therefore, regardless of memfd being
requested, we have to stick with memory-backend-file.

Signed-off-by: Michal Privoznik 
---



Reviewed-by: Daniel Henrique Barboza 


  src/qemu/qemu_command.c   |  3 ++-
  .../memfd-memory-numa.x86_64-latest.args  |  6 --
  tests/qemuxml2argvdata/memfd-memory-numa.xml  | 11 +++
  tests/qemuxml2xmltest.c   |  3 ++-
  4 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index ea513693f7..0473e7deaa 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -3052,7 +3052,8 @@ qemuBuildMemoryBackendProps(virJSONValue **backendProps,
  
  props = virJSONValueNewObject();
  
-if (def->mem.source == VIR_DOMAIN_MEMORY_SOURCE_MEMFD) {

+if (!mem->nvdimmPath &&
+def->mem.source == VIR_DOMAIN_MEMORY_SOURCE_MEMFD) {
  backendType = "memory-backend-memfd";
  
  if (useHugepage) {

diff --git a/tests/qemuxml2argvdata/memfd-memory-numa.x86_64-latest.args 
b/tests/qemuxml2argvdata/memfd-memory-numa.x86_64-latest.args
index 5e54908666..3b33db3c55 100644
--- a/tests/qemuxml2argvdata/memfd-memory-numa.x86_64-latest.args
+++ b/tests/qemuxml2argvdata/memfd-memory-numa.x86_64-latest.args
@@ -10,13 +10,15 @@ 
XDG_CONFIG_HOME=/tmp/lib/domain--1-instance-0092/.config \
  -name guest=instance-0092,debug-threads=on \
  -S \
  -object 
'{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/tmp/lib/domain--1-instance-0092/master-key.aes"}'
 \
--machine pc-i440fx-2.3,accel=kvm,usb=off,dump-guest-core=off \
+-machine pc-i440fx-2.3,accel=kvm,usb=off,dump-guest-core=off,nvdimm=on \
  -cpu qemu64 \
--m 14336 \
+-m size=14680064k,slots=16,maxmem=1099511627776k \
  -overcommit mem-lock=off \
  -smp 8,sockets=1,dies=1,cores=8,threads=1 \
  -object 
'{"qom-type":"memory-backend-memfd","id":"ram-node0","hugetlb":true,"hugetlbsize":2097152,"share":true,"prealloc":true,"size":15032385536,"host-nodes":[3],"policy":"preferred"}'
 \
  -numa node,nodeid=0,cpus=0-7,memdev=ram-node0 \
+-object 
'{"qom-type":"memory-backend-file","id":"memnvdimm0","mem-path":"/tmp/nvdimm","share":true,"prealloc":true,"size":536870912,"host-nodes":[3],"policy":"preferred"}'
 \
+-device nvdimm,node=0,memdev=memnvdimm0,id=nvdimm0,slot=0 \
  -uuid 126f2720-6f8e-45ab-a886-ec9277079a67 \
  -display none \
  -no-user-config \
diff --git a/tests/qemuxml2argvdata/memfd-memory-numa.xml 
b/tests/qemuxml2argvdata/memfd-memory-numa.xml
index 3f448790a6..d9e1a9f564 100644
--- a/tests/qemuxml2argvdata/memfd-memory-numa.xml
+++ b/tests/qemuxml2argvdata/memfd-memory-numa.xml
@@ -1,6 +1,7 @@
  
instance-0092
126f2720-6f8e-45ab-a886-ec9277079a67
+  1099511627776
14680064
14680064

@@ -41,5 +42,15 @@
  

  
+
+  
+/tmp/nvdimm
+  
+  
+523264
+0
+  
+  
+

  
diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
index 40e027aaa4..c5005d41a0 100644
--- a/tests/qemuxml2xmltest.c
+++ b/tests/qemuxml2xmltest.c
@@ -1305,7 +1305,8 @@ mymain(void)
  DO_TEST("memfd-memory-numa",
  QEMU_CAPS_OBJECT_MEMORY_MEMFD,
  QEMU_CAPS_OBJECT_MEMORY_MEMFD_HUGETLB,
-QEMU_CAPS_OBJECT_MEMORY_FILE);
+QEMU_CAPS_OBJECT_MEMORY_FILE,
+QEMU_CAPS_DEVICE_NVDIMM);
  DO_TEST("memfd-memory-default-hugepage",
  QEMU_CAPS_OBJECT_MEMORY_MEMFD,
  QEMU_CAPS_OBJECT_MEMORY_MEMFD_HUGETLB,





Re: [PATCH] virtlockd: Don't report error if lockspace exists

2021-07-07 Thread Daniel Henrique Barboza




On 6/30/21 8:17 PM, Jim Fehlig wrote:

When the qemu or libxl driver is configured to use lockd and
file_lockspace_dir is set, virtlockd emits an error when libvirtd
is retarted

May 25 15:44:31 virt81 virtlockd[7723]: Requested operation is not
valid: Lockspace for path /data/libvirtd/lockspace already exists

There is really no need to fail when the lockspace already exists,
paricularly since the user is expected to create the lockspace
specified in file_lockspace_dir. Failure to do so will prevent
starting any domains

virsh start test
error: Failed to start domain 'test'
error: Unable to open/create resource 
/data/libvirtd/lockspace/de22c4bf931e7c48b49e8ca64b477d44e78a51543e534df488b05ccd08ec5caa:
 No such file or directory

Also, virLockManagerLockDaemonSetupLockspace already has logic to ignore
the error. Since callers are not interested in the error, change
virtlockd to not report or return an error when the specified lockspace
already exists.

Signed-off-by: Jim Fehlig 
---


Reviewed-by: Daniel Henrique Barboza 



In response to my earlier query about this problem

https://listman.redhat.com/archives/libvir-list/2021-May/msg00872.html

  src/locking/lock_daemon_dispatch.c |  5 ++---
  src/locking/lock_driver_lockd.c| 11 ++-
  2 files changed, 4 insertions(+), 12 deletions(-)

diff --git a/src/locking/lock_daemon_dispatch.c 
b/src/locking/lock_daemon_dispatch.c
index e8b9832453..13e688f2e2 100644
--- a/src/locking/lock_daemon_dispatch.c
+++ b/src/locking/lock_daemon_dispatch.c
@@ -405,9 +405,8 @@ virLockSpaceProtocolDispatchCreateLockSpace(virNetServer 
*server G_GNUC_UNUSED,
  }
  
  if (virLockDaemonFindLockSpace(lockDaemon, args->path) != NULL) {

-virReportError(VIR_ERR_OPERATION_INVALID,
-   _("Lockspace for path %s already exists"),
-   args->path);
+VIR_DEBUG("Lockspace for path %s already exists", args->path);
+rv = 0;
  goto cleanup;
  }
  
diff --git a/src/locking/lock_driver_lockd.c b/src/locking/lock_driver_lockd.c

index 3a7386af30..87afdbfb78 100644
--- a/src/locking/lock_driver_lockd.c
+++ b/src/locking/lock_driver_lockd.c
@@ -281,15 +281,8 @@ static int virLockManagerLockDaemonSetupLockspace(const 
char *path)
  VIR_LOCK_SPACE_PROTOCOL_PROC_CREATE_LOCKSPACE,
  0, NULL, NULL, NULL,
  
(xdrproc_t)xdr_virLockSpaceProtocolCreateLockSpaceArgs, (char*)&args,
-(xdrproc_t)xdr_void, NULL) < 0) {
-if (virGetLastErrorCode() == VIR_ERR_OPERATION_INVALID) {
-/* The lockspace already exists */
-virResetLastError();
-rv = 0;
-} else {
-goto cleanup;
-}
-}
+(xdrproc_t)xdr_void, NULL) < 0)
+goto cleanup;
  
  rv = 0;
  





Re: [PATCH] virDomainMachineNameAppendValid: Handle special characters better

2021-07-07 Thread Daniel Henrique Barboza




On 6/25/21 11:10 AM, Michal Privoznik wrote:

When constructing guest name for machined we have to be very
cautious as machined expects a name that's basically a valid URI.
Therefore, if there's a dot it has to be followed by a letter or
a number. And if there's a sequence of two or more dashes they
should be joined into a single dash. These rules are implemented
in virDomainMachineNameAppendValid(). There's the @skip variable
which is supposed to track whether it is safe to append a dot or
a dash into name. However, the variable is set to false (meaning
it is safe to append a dot or a dash) even if the current
character we are processing is not in the set of allowed
characters (and thus skipped over).

Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1948433
Signed-off-by: Michal Privoznik 
---


Reviewed-by: Daniel Henrique Barboza 


  src/hypervisor/domain_driver.c | 8 
  tests/virsystemdtest.c | 3 +++
  2 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/src/hypervisor/domain_driver.c b/src/hypervisor/domain_driver.c
index f7d49bc38a..29e11c0447 100644
--- a/src/hypervisor/domain_driver.c
+++ b/src/hypervisor/domain_driver.c
@@ -63,18 +63,18 @@ virDomainMachineNameAppendValid(virBuffer *buf,
  break;
  
  if (*name == '.' || *name == '-') {

-if (!skip)
+if (!skip) {
  virBufferAddChar(buf, *name);
-skip = true;
+skip = true;
+}
  continue;
  }
  
-skip = false;

-
  if (!strchr(HOSTNAME_CHARS, *name))
  continue;
  
  virBufferAddChar(buf, *name);

+skip = false;
  }
  
  /* trailing dashes or dots are not allowed */

diff --git a/tests/virsystemdtest.c b/tests/virsystemdtest.c
index f1c9a4ee5f..a09b428a8a 100644
--- a/tests/virsystemdtest.c
+++ b/tests/virsystemdtest.c
@@ -736,6 +736,9 @@ mymain(void)
  TEST_MACHINE("demo.-.test.", NULL, 11, "qemu-11-demo.test");
  TEST_MACHINE("demo", "/tmp/root1", 1, "qemu-embed-0991f456-1-demo");
  TEST_MACHINE("demo", "/tmp/root2", 1, "qemu-embed-95d47ff5-1-demo");
+TEST_MACHINE("|.-m", NULL, 1, "qemu-1-m");
+
TEST_MACHINE("Auto-esx7.0-rhel7.9-special-characters~!@#$%^&*_=+,?><:;|.\"[]()`\\-m",
+ NULL, 1, "qemu-1-Auto-esx7.0-rhel7.9-special-characters.m");
  
  # define TESTS_PM_SUPPORT_HELPER(name, function) \

  do { \





Re: [PATCH v3 1/6] schemas: Make SEV policy on launch security optional

2021-06-22 Thread Daniel Henrique Barboza




On 6/22/21 10:10 AM, Boris Fiuczynski wrote:

Change launch security policy of type SEV from required to
optional and add a test to ensure the required launch security
policy remains required when launch security type is SEV.

Signed-off-by: Boris Fiuczynski 
---


Reviewed-by: Daniel Henrique Barboza 


  docs/schemas/domaincommon.rng | 12 ---
  src/conf/domain_conf.c|  3 +-
  ...urity-sev-missing-policy.x86_64-2.12.0.err |  1 +
  .../launch-security-sev-missing-policy.xml| 34 +++
  tests/qemuxml2argvtest.c  |  1 +
  5 files changed, 46 insertions(+), 5 deletions(-)
  create mode 100644 
tests/qemuxml2argvdata/launch-security-sev-missing-policy.x86_64-2.12.0.err
  create mode 100644 
tests/qemuxml2argvdata/launch-security-sev-missing-policy.xml

diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 5ea14b6dbf..8c1b6c3a09 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -483,7 +483,9 @@

  

-sev
+
+  sev
+


  
@@ -496,9 +498,11 @@
  

  
-
-  
-
+
+  
+
+  
+
  

  
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index f65509d8ec..af2fd03d3c 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -14749,7 +14749,8 @@ virDomainSEVDefParseXML(xmlNodePtr sevNode,
  
  if (virXPathULongHex("string(./policy)", ctxt, &policy) < 0) {

  virReportError(VIR_ERR_XML_ERROR, "%s",
-   _("failed to get launch security policy"));
+   _("failed to get launch security policy for "
+ "launch security type SEV"));
  goto error;
  }
  
diff --git a/tests/qemuxml2argvdata/launch-security-sev-missing-policy.x86_64-2.12.0.err b/tests/qemuxml2argvdata/launch-security-sev-missing-policy.x86_64-2.12.0.err

new file mode 100644
index 00..2019c8bb13
--- /dev/null
+++ 
b/tests/qemuxml2argvdata/launch-security-sev-missing-policy.x86_64-2.12.0.err
@@ -0,0 +1 @@
+XML error: failed to get launch security policy for launch security type SEV
diff --git a/tests/qemuxml2argvdata/launch-security-sev-missing-policy.xml 
b/tests/qemuxml2argvdata/launch-security-sev-missing-policy.xml
new file mode 100644
index 00..5461b06c9d
--- /dev/null
+++ b/tests/qemuxml2argvdata/launch-security-sev-missing-policy.xml
@@ -0,0 +1,34 @@
+
+  QEMUGuest1
+  c7a5fdbd-edaf-9455-926a-d65c16db1809
+  219100
+  219100
+  1
+  
+hvm
+
+  
+  
+  destroy
+  restart
+  destroy
+  
+/usr/bin/qemu-system-x86_64
+
+  
+  
+  
+  
+
+
+
+
+
+
+
+  
+  
+AQAOQAOQAOQAOQAOAAA
+IHAVENOIDEABUTJUSTPROVIDINGASTRING
+  
+
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index 9df28658b9..ef6afae586 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -3459,6 +3459,7 @@ mymain(void)
  DO_TEST_CAPS_VER("launch-security-sev", "2.12.0");
  DO_TEST_CAPS_VER("launch-security-sev", "6.0.0");
  DO_TEST_CAPS_VER("launch-security-sev-missing-platform-info", "2.12.0");
+DO_TEST_CAPS_VER_PARSE_ERROR("launch-security-sev-missing-policy", 
"2.12.0");
  
  DO_TEST_CAPS_LATEST("vhost-user-fs-fd-memory");

  DO_TEST_CAPS_LATEST("vhost-user-fs-hugepages");





Re: [PATCH v3 3/6] conf: refactor launch security to allow more types

2021-06-22 Thread Daniel Henrique Barboza




On 6/22/21 10:10 AM, Boris Fiuczynski wrote:

Adding virDomainSecDef for general launch security data
and moving virDomainSEVDef as an element for SEV data.

Signed-off-by: Boris Fiuczynski 
---


Reviewed-by: Daniel Henrique Barboza 


  src/conf/domain_conf.c  | 127 +++-
  src/conf/domain_conf.h  |  11 +++-
  src/conf/virconftypes.h |   2 +
  src/qemu/qemu_cgroup.c  |   4 +-
  src/qemu/qemu_command.c |  44 +++--
  src/qemu/qemu_driver.c  |   3 +-
  src/qemu/qemu_firmware.c|  33 ++
  src/qemu/qemu_namespace.c   |  20 --
  src/qemu/qemu_process.c |  33 --
  src/qemu/qemu_validate.c|  22 +--
  src/security/security_dac.c |   6 +-
  11 files changed, 218 insertions(+), 87 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 93ec50ff5d..2bd5210a16 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -3502,6 +3502,19 @@ virDomainSEVDefFree(virDomainSEVDef *def)
  g_free(def);
  }
  
+

+void
+virDomainSecDefFree(virDomainSecDef *def)
+{
+if (!def)
+return;
+
+virDomainSEVDefFree(def->sev);
+
+g_free(def);
+}
+
+
  static void
  virDomainOSDefClear(virDomainOSDef *os)
  {
@@ -3703,7 +3716,7 @@ void virDomainDefFree(virDomainDef *def)
  if (def->namespaceData && def->ns.free)
  (def->ns.free)(def->namespaceData);
  
-virDomainSEVDefFree(def->sev);

+virDomainSecDefFree(def->sec);
  
  xmlFreeNode(def->metadata);
  
@@ -14720,57 +14733,72 @@ virDomainSEVDefParseXML(xmlNodePtr sevNode,

  {
  VIR_XPATH_NODE_AUTORESTORE(ctxt)
  unsigned long policy;
-g_autofree char *type = NULL;
  int rc = -1;
  
  g_autoptr(virDomainSEVDef) def = g_new0(virDomainSEVDef, 1);
  
  ctxt->node = sevNode;
  
-if (!(type = virXMLPropString(sevNode, "type"))) {

+if (virXPathULongHex("string(./policy)", ctxt, &policy) < 0) {
  virReportError(VIR_ERR_XML_ERROR, "%s",
-   _("missing launch security type"));
+   _("failed to get launch security policy for "
+ "launch security type SEV"));
  return NULL;
  }
  
-def->sectype = virDomainLaunchSecurityTypeFromString(type);

-switch ((virDomainLaunchSecurity) def->sectype) {
-case VIR_DOMAIN_LAUNCH_SECURITY_SEV:
-if (virXPathULongHex("string(./policy)", ctxt, &policy) < 0) {
-virReportError(VIR_ERR_XML_ERROR, "%s",
-   _("failed to get launch security policy for "
- "launch security type SEV"));
-return NULL;
-}
+/* the following attributes are platform dependent and if missing,
+ * we can autofill them from domain capabilities later
+ */
+rc = virXPathUInt("string(./cbitpos)", ctxt, &def->cbitpos);
+if (rc == 0) {
+def->haveCbitpos = true;
+} else if (rc == -2) {
+virReportError(VIR_ERR_XML_ERROR, "%s",
+   _("Invalid format for launch security cbitpos"));
+return NULL;
+}
  
-/* the following attributes are platform dependent and if missing,

- * we can autofill them from domain capabilities later
- */
-rc = virXPathUInt("string(./cbitpos)", ctxt, &def->cbitpos);
-if (rc == 0) {
-def->haveCbitpos = true;
-} else if (rc == -2) {
-virReportError(VIR_ERR_XML_ERROR, "%s",
-   _("Invalid format for launch security cbitpos"));
-return NULL;
-}
+rc = virXPathUInt("string(./reducedPhysBits)", ctxt,
+  &def->reduced_phys_bits);
+if (rc == 0) {
+def->haveReducedPhysBits = true;
+} else if (rc == -2) {
+virReportError(VIR_ERR_XML_ERROR, "%s",
+   _("Invalid format for launch security "
+ "reduced-phys-bits"));
+return NULL;
+}
  
-rc = virXPathUInt("string(./reducedPhysBits)", ctxt,

-  &def->reduced_phys_bits);
-if (rc == 0) {
-def->haveReducedPhysBits = true;
-} else if (rc == -2) {
-virReportError(VIR_ERR_XML_ERROR, "%s",
-   _("Invalid format for launch security "
- "reduced-phys-bits"));
-return NULL;
-}
+def->policy = policy;
+def->dh_cert = virXPathString("string(./dhCert)", ctxt);
+def->session = virXPathString("string(./session)", ctxt);
+
+return g_steal_pointer(&def);
+}
+

Re: [PATCH v3 2/6] conf: modernize SEV XML parse and format methods

2021-06-22 Thread Daniel Henrique Barboza




On 6/22/21 10:10 AM, Boris Fiuczynski wrote:

Make use of virDomainLaunchSecurity enum and automatic memory freeing.

Signed-off-by: Boris Fiuczynski 
---


Reviewed-by: Daniel Henrique Barboza 


  src/conf/domain_conf.c | 123 +
  src/conf/domain_conf.h |   2 +
  2 files changed, 64 insertions(+), 61 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index af2fd03d3c..93ec50ff5d 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -3490,7 +3490,7 @@ virDomainResctrlDefFree(virDomainResctrlDef *resctrl)
  }
  
  
-static void

+void
  virDomainSEVDefFree(virDomainSEVDef *def)
  {
  if (!def)
@@ -14719,73 +14719,66 @@ virDomainSEVDefParseXML(xmlNodePtr sevNode,
  xmlXPathContextPtr ctxt)
  {
  VIR_XPATH_NODE_AUTORESTORE(ctxt)
-virDomainSEVDef *def;
  unsigned long policy;
  g_autofree char *type = NULL;
  int rc = -1;
  
-def = g_new0(virDomainSEVDef, 1);

+g_autoptr(virDomainSEVDef) def = g_new0(virDomainSEVDef, 1);
  
  ctxt->node = sevNode;
  
  if (!(type = virXMLPropString(sevNode, "type"))) {

  virReportError(VIR_ERR_XML_ERROR, "%s",
 _("missing launch security type"));
-goto error;
+return NULL;
  }
  
  def->sectype = virDomainLaunchSecurityTypeFromString(type);

  switch ((virDomainLaunchSecurity) def->sectype) {
  case VIR_DOMAIN_LAUNCH_SECURITY_SEV:
-break;
+if (virXPathULongHex("string(./policy)", ctxt, &policy) < 0) {
+virReportError(VIR_ERR_XML_ERROR, "%s",
+   _("failed to get launch security policy for "
+ "launch security type SEV"));
+return NULL;
+}
+
+/* the following attributes are platform dependent and if missing,
+ * we can autofill them from domain capabilities later
+ */
+rc = virXPathUInt("string(./cbitpos)", ctxt, &def->cbitpos);
+if (rc == 0) {
+def->haveCbitpos = true;
+} else if (rc == -2) {
+virReportError(VIR_ERR_XML_ERROR, "%s",
+   _("Invalid format for launch security cbitpos"));
+return NULL;
+}
+
+rc = virXPathUInt("string(./reducedPhysBits)", ctxt,
+  &def->reduced_phys_bits);
+if (rc == 0) {
+def->haveReducedPhysBits = true;
+} else if (rc == -2) {
+virReportError(VIR_ERR_XML_ERROR, "%s",
+   _("Invalid format for launch security "
+ "reduced-phys-bits"));
+return NULL;
+}
+
+def->policy = policy;
+def->dh_cert = virXPathString("string(./dhCert)", ctxt);
+def->session = virXPathString("string(./session)", ctxt);
+
+return g_steal_pointer(&def);
  case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
  case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
  default:
  virReportError(VIR_ERR_XML_ERROR,
 _("unsupported launch security type '%s'"),
 type);
-goto error;
-}
-
-if (virXPathULongHex("string(./policy)", ctxt, &policy) < 0) {
-virReportError(VIR_ERR_XML_ERROR, "%s",
-   _("failed to get launch security policy for "
- "launch security type SEV"));
-goto error;
-}
-
-/* the following attributes are platform dependent and if missing, we can
- * autofill them from domain capabilities later
- */
-rc = virXPathUInt("string(./cbitpos)", ctxt, &def->cbitpos);
-if (rc == 0) {
-def->haveCbitpos = true;
-} else if (rc == -2) {
-virReportError(VIR_ERR_XML_ERROR, "%s",
-   _("Invalid format for launch security cbitpos"));
-goto error;
-}
-
-rc = virXPathUInt("string(./reducedPhysBits)", ctxt,
-  &def->reduced_phys_bits);
-if (rc == 0) {
-def->haveReducedPhysBits = true;
-} else if (rc == -2) {
-virReportError(VIR_ERR_XML_ERROR, "%s",
-   _("Invalid format for launch security "
- "reduced-phys-bits"));
-goto error;
+return NULL;
  }
-
-def->policy = policy;
-def->dh_cert = virXPathString("string(./dhCert)", ctxt);
-def->session = virXPathString("string(./session)", ctxt);
-
-return def;
-
- error:
-virDomainSEVDefFree(def);
-return NULL;
  }
  
  
@@ -26844

Re: [PATCH 1/1] domain_validate.c: fix virDomainDefFSValidate() when fs->dst is NULL

2021-06-17 Thread Daniel Henrique Barboza




On 6/17/21 5:55 AM, Jano Tomko wrote:

On 6/17/21 9:03 AM, Peter Krempa wrote:

On Wed, Jun 16, 2021 at 18:30:08 -0300, Daniel Henrique Barboza wrote:

Commit 56dcdec1ac81 ("conf: reject duplicate virtiofs tags") added
validation code to reject duplicated virtiofs tags. But the 
element is not always present, meaning that fs->dst can be NULL at that
point.



The tag should be mandatory, the test case in question was broken.


I see. That was my first guess, but then by reading the docs I got the
impression that the 'target' tag was optional for filesystem=mount.

In fact, by reading it again now, I see that other optional attributes
(e.g. binary) are marked as optional right on the start. Not sure why
I thought 'target' was optional first time I read this ...



It should be fixed now.


It is. Thanks!




Jano


If there is no "" tag then the validation will fail in
virHashAddEntry() because fs->dst will be NULL. This is tested in
qemuxml2xml vhost-user-fs-sock, which is since then not passing:

1020) QEMU XML-2-XML-inactive vhost-user-fs-sock  ... Expected result code=0 
but received code=1
FAILED
1021) QEMU XML-2-XML-active vhost-user-fs-sock  ... Expected result code=0 but 
received code=1
FAILED

The '' tag is not mandatory, so let's consider that fs->dst
being NULL is a feasible scenario an adapt virDomainDefFSValidate()
accordingly.

Signed-off-by: Daniel Henrique Barboza 
---
  src/conf/domain_validate.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c
index 9422b00964..cf8b43b845 100644
--- a/src/conf/domain_validate.c
+++ b/src/conf/domain_validate.c
@@ -1504,7 +1504,7 @@ virDomainDefFSValidate(const virDomainDef *def)
  for (i = 0; i < def->nfss; i++) {
  const virDomainFSDef *fs = def->fss[i];
  
-if (fs->fsdriver != VIR_DOMAIN_FS_DRIVER_TYPE_VIRTIOFS)

+if (fs->fsdriver != VIR_DOMAIN_FS_DRIVER_TYPE_VIRTIOFS || !fs->dst)
  continue;
  
  if (virHashHasEntry(dsts, fs->dst)) {

--


This should not be necessary once Jano pushes the patch moving the
validation of the presence of the virtiofs target, which was originally
before the patch that introduced the breakage, but I've requested
changes to it.

But lets see what Jano thinks about this.







Re: [PATCH] qemu: Don't set NVRAM label when creating it

2021-06-16 Thread Daniel Henrique Barboza




On 6/9/21 12:19 PM, Michal Privoznik wrote:

The NVRAM label is set in qemuSecuritySetAllLabel(). There's no
need to set its label upfront. In fact, setting it twice creates
an imbalance because it's unset only once which mangles seclabel
remembering. However, plain removal of the
qemuSecurityDomainSetPathLabel() undoes the fix for the original
bug (when dynamic ownership is off then the NVRAM is not created
with cfg->user and cfg->group but as root:root). Therefore, we
have to switch to virFileOpenAs() and pass cfg->user and
cfg->group and VIR_FILE_OPEN_FORCE_OWNER flag. There's no need to
pass VIR_FILE_OPEN_FORCE_MODE because the file will be created
with the proper mode.

Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1969347
Fixes: bcdaa91a27b5b2d103535270a6a287efe6cd8bfb
Signed-off-by: Michal Privoznik 
---


Reviewed-by: Daniel Henrique Barboza 



  src/qemu/qemu_process.c | 15 +--
  1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index c37687f249..2b03b0ab98 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -4538,16 +4538,19 @@ qemuPrepareNVRAM(virQEMUDriver *driver,
  goto cleanup;
  }
  
-if ((dstFD = qemuDomainOpenFile(driver, vm, loader->nvram,

-O_WRONLY | O_CREAT | O_EXCL,
-NULL)) < 0)
+if ((dstFD = virFileOpenAs(loader->nvram,
+   O_WRONLY | O_CREAT | O_EXCL,
+   S_IRUSR | S_IWUSR,
+   cfg->user, cfg->group,
+   VIR_FILE_OPEN_FORCE_OWNER)) < 0) {
+virReportSystemError(-dstFD,
+ _("Failed to create file '%s'"),
+ loader->nvram);
  goto cleanup;
+}
  
  created = true;
  
-if (qemuSecurityDomainSetPathLabel(driver, vm, loader->nvram, false) < 0)

-goto cleanup;
-
  do {
  char buf[1024];
  





[PATCH 1/1] domain_validate.c: fix virDomainDefFSValidate() when fs->dst is NULL

2021-06-16 Thread Daniel Henrique Barboza
Commit 56dcdec1ac81 ("conf: reject duplicate virtiofs tags") added
validation code to reject duplicated virtiofs tags. But the 
element is not always present, meaning that fs->dst can be NULL at that
point.

If there is no "" tag then the validation will fail in
virHashAddEntry() because fs->dst will be NULL. This is tested in
qemuxml2xml vhost-user-fs-sock, which is since then not passing:

1020) QEMU XML-2-XML-inactive vhost-user-fs-sock  ... Expected result code=0 
but received code=1
FAILED
1021) QEMU XML-2-XML-active vhost-user-fs-sock  ... Expected result code=0 but 
received code=1
FAILED

The '' tag is not mandatory, so let's consider that fs->dst
being NULL is a feasible scenario an adapt virDomainDefFSValidate()
accordingly.

Signed-off-by: Daniel Henrique Barboza 
---
 src/conf/domain_validate.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c
index 9422b00964..cf8b43b845 100644
--- a/src/conf/domain_validate.c
+++ b/src/conf/domain_validate.c
@@ -1504,7 +1504,7 @@ virDomainDefFSValidate(const virDomainDef *def)
 for (i = 0; i < def->nfss; i++) {
 const virDomainFSDef *fs = def->fss[i];
 
-if (fs->fsdriver != VIR_DOMAIN_FS_DRIVER_TYPE_VIRTIOFS)
+if (fs->fsdriver != VIR_DOMAIN_FS_DRIVER_TYPE_VIRTIOFS || !fs->dst)
 continue;
 
 if (virHashHasEntry(dsts, fs->dst)) {
-- 
2.31.1



Re: Add options to device xml to skip reattach of pci passthrough devices.

2021-06-16 Thread Daniel Henrique Barboza




On 6/9/21 4:38 PM, Manish Mishra wrote:

Hi Everyone,

We want to add extra options to device xml to skip reattach of pci passthrough 
devices. Following is xml format for pci passthrough devices added to domain as 
of now.



   

   

   



When we pass managed=’yes’ flag through xml, libvirt takes responsibility of 
detaching device on domain(guest VM) start and reattaching on domain shutdown. 
We observed some issues where guest VM shutdown may take long time, blocked for 
reattach operation on pci passthrough device. As domain lock is held during 
this time it also makes libvirt mostly inactive as it blocks even basic 
operations like (virsh list). Reattaching of device to host can block due to 
reasons like buggy driver or initialization of device itself can take long time 
in some cases.


I am more interested in hearing about the problem with this faulty buggy
driver holding domain lock during device reattach and compromising 'virsh'
operations, and see if there's something to do to mitigate that, instead
of creating a XML workaround for a driver problem.



We want to pass following extra options to resolve this:

 1. *skipReAttach*(optional flag)

In some cases we do not need to reattach device to host as it may be reserved 
only for guests, with this flag we can skip reattach operation on host.  We do 
not want to modify managed flag to avoid regression, so thinking of adding new 
optional flag.

 2. *reAttachDriverName*(optional flag)

Name of driver to which we want to attach instead of default, to avoid 
reattaching to buggy driver. Currently libvirt asks host to auto selects driver 
for device.

Yes we can use managed=’no’ but in that case user has to take responsibility of 
detaching device before starting domain which we do not want. Please let us 
know your views on this.


The case you mentioned above, "we do not need to reattach device to host
as it may be reserved only for guests", is one of the most common uses
we have for managed='no' AFAIK. The user/sysadm must detach the device
from the host, but it's only one time. After that the device can remain
detached from the host, and guests can use it freely as long as you
don't reboot the host (or reattach the device back). This scenario
you described fit the managed='no' mechanics fine IMO.

If you want to automate the detach process, you can use a Libvirt QEMU
hook (/etc/libvirt/hooks/qemu) to make the device detach when starting
the domain, in case the device isn't already detached. Note that
this has the same effect of the "skipReAttach" option you proposed.

Making a design around faulty drivers isn't ideal. If the driver you're
using starts to have problems with the detach operation as well, 'skipReAttach'
will do you no good. You'll have to fall back to 'managed=no' to circumvent
that.

Even if we discard the motivation, I'm not sure about the utility of having
more forms of PCI assignment management (e.g managed=yes|no|detach|reattach).
managed=yes|no seems to cover most use cases where the device driver works
properly.


Laine, what do you think?




Thanks,


Daniel




Thanks

Manish Mishra





Re: Migration capabilities is not reset after the libvirtd service restart

2021-06-16 Thread Daniel Henrique Barboza




On 6/11/21 9:40 AM, Huangzhichao wrote:

Hi Everyone,

We find migration capabilities is not reset after restarting libvirtd, it would 
cause problem in the following scene:

Version: libvirt release 7.4.0

Step 1.  create a VM and query migration capabilities, mark the return content 
as “Cap A”.

Step 2.  stop the source libvirtd service when executing live migration, then 
migration failed.

Step 3.  restart the source libvirtd service, then query migration 
capabilities, mark the return content  as “Cap B”.

“Cap A” is different from “Cap B”, because the source libvirtd service would 
set migration capabilities when executing live migration.

We find that there is a patch may cause this problem.

Link:

https://libvirt.org/git/?p=libvirt.git;a=commitdiff;h=a1dec315c9ad87a198245db0077ef80778621392
 




I'm not sure this patch is the culprit here. IMO the problem seems to
be with the refresh of priv->migrationCaps bitmap in the situation you
described. The migrationCaps from the failed migration are being restored
in libvirtd restart.




When we roll back this patch, “CAP A” would be the same as “CAP B”.

Do you have any suggestion ?


I suggest looking into how priv->migrationCaps is being fetched in that
scenario. qemuMigrationCapsCheck() seems like a good place to start
digging since it's the only place where priv->migrationCaps bits are
being set.



Thanks,


Daniel



Thanks.





[PATCH 2/5] qemu: add 'pef-guest' capability

2021-06-02 Thread Daniel Henrique Barboza
This capability will be used in the papr-pef launch security type.

Signed-off-by: Daniel Henrique Barboza 
---
 src/qemu/qemu_capabilities.c| 2 ++
 src/qemu/qemu_capabilities.h| 1 +
 tests/qemucapabilitiesdata/caps_6.1.0.ppc64.xml | 1 +
 3 files changed, 4 insertions(+)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 44585927b5..912cb60640 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -631,6 +631,7 @@ VIR_ENUM_IMPL(virQEMUCaps,
   "acpi-index",
   "input-linux",
   "s390-pv-guest",
+  "pef-guest",
 );
 
 
@@ -1351,6 +1352,7 @@ struct virQEMUCapsStringFlags virQEMUCapsObjectTypes[] = {
 { "vhost-user-blk", QEMU_CAPS_DEVICE_VHOST_USER_BLK },
 { "input-linux", QEMU_CAPS_INPUT_LINUX },
 { "s390-pv-guest", QEMU_CAPS_S390_PV_GUEST },
+{ "pef-guest", QEMU_CAPS_PAPR_PEF_GUEST },
 };
 
 
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index b9fa2e4bb1..4da0d5f673 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -611,6 +611,7 @@ typedef enum { /* virQEMUCapsFlags grouping marker for 
syntax-check */
 QEMU_CAPS_ACPI_INDEX, /* PCI device 'acpi-index' property */
 QEMU_CAPS_INPUT_LINUX, /* -object input-linux */
 QEMU_CAPS_S390_PV_GUEST, /* -object s390-pv-guest,... */
+QEMU_CAPS_PAPR_PEF_GUEST, /* -object pef-guest,... */
 
 QEMU_CAPS_LAST /* this must always be the last item */
 } virQEMUCapsFlags;
diff --git a/tests/qemucapabilitiesdata/caps_6.1.0.ppc64.xml 
b/tests/qemucapabilitiesdata/caps_6.1.0.ppc64.xml
index 87d4f41d68..cad6393ffe 100644
--- a/tests/qemucapabilitiesdata/caps_6.1.0.ppc64.xml
+++ b/tests/qemucapabilitiesdata/caps_6.1.0.ppc64.xml
@@ -213,6 +213,7 @@
   
   
   
+  
   650
   0
   42900243
-- 
2.31.1



[PATCH 5/5] docs/formatdomain.rst: add 'papr-pef' launchSecurity docs

2021-06-02 Thread Daniel Henrique Barboza
Signed-off-by: Daniel Henrique Barboza 
---
 docs/formatdomain.rst | 4 
 1 file changed, 4 insertions(+)

diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst
index ab1307910d..4102327aa8 100644
--- a/docs/formatdomain.rst
+++ b/docs/formatdomain.rst
@@ -8067,6 +8067,10 @@ IBM Secure Execution. For more required host and guest 
preparation steps, see
 `Protected Virtualization on s390 `__
 :since:`Since 7.4.0`
 
+Specifying  in a ppc64 domain enables the
+guest to run in secure mode. This mode relies on the hardware having PEF
+(Protected Execution Facility) support.
+:since:`Since 7.5.0`
 
 The contents of the  element is used to provide
 the guest owners input used for creating an encrypted VM using the AMD SEV
-- 
2.31.1



[PATCH 4/5] tests: add tests for 'papr-pef' support

2021-06-02 Thread Daniel Henrique Barboza
Signed-off-by: Daniel Henrique Barboza 
---
 .../launch-security-papr-pef.xml  | 22 ++
 tests/genericxml2xmltest.c|  1 +
 ...y-papr-pef-ignore-policy.ppc64-latest.args | 30 +++
 ...launch-security-papr-pef-ignore-policy.xml | 19 
 ...launch-security-papr-pef.ppc64-latest.args | 30 +++
 .../launch-security-papr-pef.xml  | 16 ++
 tests/qemuxml2argvtest.c  |  3 ++
 7 files changed, 121 insertions(+)
 create mode 100644 tests/genericxml2xmlindata/launch-security-papr-pef.xml
 create mode 100644 
tests/qemuxml2argvdata/launch-security-papr-pef-ignore-policy.ppc64-latest.args
 create mode 100644 
tests/qemuxml2argvdata/launch-security-papr-pef-ignore-policy.xml
 create mode 100644 
tests/qemuxml2argvdata/launch-security-papr-pef.ppc64-latest.args
 create mode 100644 tests/qemuxml2argvdata/launch-security-papr-pef.xml

diff --git a/tests/genericxml2xmlindata/launch-security-papr-pef.xml 
b/tests/genericxml2xmlindata/launch-security-papr-pef.xml
new file mode 100644
index 00..f5a9fe9ed2
--- /dev/null
+++ b/tests/genericxml2xmlindata/launch-security-papr-pef.xml
@@ -0,0 +1,22 @@
+
+  guest
+  1ccfd97d-5eb4-478a-bbe6-88d254c16db7
+  524288
+  524288
+  1
+  
+hvm
+
+  
+  
+  destroy
+  restart
+  destroy
+  
+/usr/bin/qemu-system-ppc64
+
+
+
+  
+  
+
diff --git a/tests/genericxml2xmltest.c b/tests/genericxml2xmltest.c
index eb15f66c3c..82decff827 100644
--- a/tests/genericxml2xmltest.c
+++ b/tests/genericxml2xmltest.c
@@ -235,6 +235,7 @@ mymain(void)
 DO_TEST("launch-security-sev");
 DO_TEST("launch-security-s390-pv");
 DO_TEST_DIFFERENT("launch-security-s390-pv-ignore-policy");
+DO_TEST("launch-security-papr-pef");
 
 DO_TEST_DIFFERENT("cputune");
 DO_TEST("device-backenddomain");
diff --git 
a/tests/qemuxml2argvdata/launch-security-papr-pef-ignore-policy.ppc64-latest.args
 
b/tests/qemuxml2argvdata/launch-security-papr-pef-ignore-policy.ppc64-latest.args
new file mode 100644
index 00..6ea120c2d1
--- /dev/null
+++ 
b/tests/qemuxml2argvdata/launch-security-papr-pef-ignore-policy.ppc64-latest.args
@@ -0,0 +1,30 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/tmp/lib/domain--1-guest \
+USER=test \
+LOGNAME=test \
+XDG_DATA_HOME=/tmp/lib/domain--1-guest/.local/share \
+XDG_CACHE_HOME=/tmp/lib/domain--1-guest/.cache \
+XDG_CONFIG_HOME=/tmp/lib/domain--1-guest/.config \
+/usr/bin/qemu-system-ppc64 \
+-name guest=guest,debug-threads=on \
+-S \
+-object 
'{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/tmp/lib/domain--1-guest/master-key.aes"}'
 \
+-machine 
pseries,accel=tcg,usb=off,dump-guest-core=off,confidential-guest-support=pef0,memory-backend=ppc_spapr.ram
 \
+-cpu POWER9 \
+-m 512 \
+-object 
'{"qom-type":"memory-backend-ram","id":"ppc_spapr.ram","size":536870912}' \
+-overcommit mem-lock=off \
+-smp 1,sockets=1,cores=1,threads=1 \
+-uuid 1ccfd97d-5eb4-478a-bbe6-88d254c16db7 \
+-display none \
+-no-user-config \
+-nodefaults \
+-chardev socket,id=charmonitor,fd=1729,server=on,wait=off \
+-mon chardev=charmonitor,id=monitor,mode=control \
+-rtc base=utc \
+-no-shutdown \
+-boot strict=on \
+-audiodev id=audio1,driver=none \
+-object '{"qom-type":"pef-guest","id":"pef0"}' \
+-msg timestamp=on
diff --git a/tests/qemuxml2argvdata/launch-security-papr-pef-ignore-policy.xml 
b/tests/qemuxml2argvdata/launch-security-papr-pef-ignore-policy.xml
new file mode 100644
index 00..07b635395f
--- /dev/null
+++ b/tests/qemuxml2argvdata/launch-security-papr-pef-ignore-policy.xml
@@ -0,0 +1,19 @@
+
+  guest
+  1ccfd97d-5eb4-478a-bbe6-88d254c16db7
+  524288
+  1
+  
+hvm
+  
+  
+/usr/bin/qemu-system-ppc64
+
+
+
+  
+  
+AQAOQAOQAOQAOQAOAAA
+IHAVENOIDEABUTJUSTPROVIDINGASTRING
+  
+
diff --git a/tests/qemuxml2argvdata/launch-security-papr-pef.ppc64-latest.args 
b/tests/qemuxml2argvdata/launch-security-papr-pef.ppc64-latest.args
new file mode 100644
index 00..6ea120c2d1
--- /dev/null
+++ b/tests/qemuxml2argvdata/launch-security-papr-pef.ppc64-latest.args
@@ -0,0 +1,30 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/tmp/lib/domain--1-guest \
+USER=test \
+LOGNAME=test \
+XDG_DATA_HOME=/tmp/lib/domain--1-guest/.local/share \
+XDG_CACHE_HOME=/tmp/lib/domain--1-guest/.cache \
+XDG_CONFIG_HOME=/tmp/lib/domain--1-guest/.config \
+/usr/bin/qemu-system-ppc64 \
+-name guest=guest,debug-threads=on \
+-S \
+-object 
'{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/tmp/lib/domain--1-guest/master-key.aes"}'
 \
+-machine 
pseries,a

[PATCH 3/5] conf, qemu: add 'papr-pef' launch security type

2021-06-02 Thread Daniel Henrique Barboza
This patch adds the 'papr-pef' launch security type for the QEMU
driver.

Signed-off-by: Daniel Henrique Barboza 
---
 docs/schemas/domaincommon.rng |  1 +
 src/conf/domain_conf.c|  3 +++
 src/conf/domain_conf.h|  1 +
 src/qemu/qemu_command.c   | 26 ++
 src/qemu/qemu_namespace.c |  1 +
 src/qemu/qemu_process.c   |  1 +
 src/qemu/qemu_validate.c  |  8 
 7 files changed, 41 insertions(+)

diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 029ae7b1d4..e0fc18889a 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -486,6 +486,7 @@
 
   sev
   s390-pv
+  papr-pef
 
   
   
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 9a9aea94d9..838386e6b7 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -1402,6 +1402,7 @@ VIR_ENUM_IMPL(virDomainLaunchSecurity,
   "",
   "sev",
   "s390-pv",
+  "papr-pef",
 );
 
 static virClass *virDomainObjClass;
@@ -14781,6 +14782,7 @@ virDomainSecDefParseXML(xmlNodePtr lsecNode,
 return NULL;
 break;
 case VIR_DOMAIN_LAUNCH_SECURITY_PV:
+case VIR_DOMAIN_LAUNCH_SECURITY_PAPR_PEF:
 break;
 case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
 case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
@@ -26884,6 +26886,7 @@ virDomainSecDefFormat(virBuffer *buf, virDomainSecDef 
*sec)
 }
 
 case VIR_DOMAIN_LAUNCH_SECURITY_PV:
+case VIR_DOMAIN_LAUNCH_SECURITY_PAPR_PEF:
 virBufferAsprintf(buf, "\n",
   virDomainLaunchSecurityTypeToString(sec->sectype));
 break;
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 37d0085699..e0731f7025 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -2644,6 +2644,7 @@ typedef enum {
 VIR_DOMAIN_LAUNCH_SECURITY_NONE,
 VIR_DOMAIN_LAUNCH_SECURITY_SEV,
 VIR_DOMAIN_LAUNCH_SECURITY_PV,
+VIR_DOMAIN_LAUNCH_SECURITY_PAPR_PEF,
 
 VIR_DOMAIN_LAUNCH_SECURITY_LAST,
 } virDomainLaunchSecurity;
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index dcf7c61ef5..46e4bd555f 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -6930,6 +6930,9 @@ qemuBuildMachineCommandLine(virCommand *cmd,
 case VIR_DOMAIN_LAUNCH_SECURITY_PV:
 virBufferAddLit(&buf, ",confidential-guest-support=pv0");
 break;
+case VIR_DOMAIN_LAUNCH_SECURITY_PAPR_PEF:
+virBufferAddLit(&buf, ",confidential-guest-support=pef0");
+break;
 case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
 break;
 case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
@@ -9837,6 +9840,26 @@ qemuBuildPVCommandLine(virDomainObj *vm, virCommand *cmd)
 }
 
 
+static int
+qemuBuildPaprPEFCommandLine(virDomainObj *vm, virCommand *cmd)
+{
+g_autoptr(virJSONValue) props = NULL;
+g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER;
+qemuDomainObjPrivate *priv = vm->privateData;
+
+if (qemuMonitorCreateObjectProps(&props, "pef-guest", "pef0",
+ NULL) < 0)
+return -1;
+
+if (qemuBuildObjectCommandlineFromJSON(&buf, props, priv->qemuCaps) < 0)
+return -1;
+
+virCommandAddArg(cmd, "-object");
+virCommandAddArgBuffer(cmd, &buf);
+return 0;
+}
+
+
 static int
 qemuBuildSecCommandLine(virDomainObj *vm, virCommand *cmd,
 virDomainSecDef *sec)
@@ -9851,6 +9874,9 @@ qemuBuildSecCommandLine(virDomainObj *vm, virCommand *cmd,
 case VIR_DOMAIN_LAUNCH_SECURITY_PV:
 return qemuBuildPVCommandLine(vm, cmd);
 break;
+case VIR_DOMAIN_LAUNCH_SECURITY_PAPR_PEF:
+return qemuBuildPaprPEFCommandLine(vm, cmd);
+break;
 case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
 break;
 case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
diff --git a/src/qemu/qemu_namespace.c b/src/qemu/qemu_namespace.c
index 156ee84292..9d1b806872 100644
--- a/src/qemu/qemu_namespace.c
+++ b/src/qemu/qemu_namespace.c
@@ -608,6 +608,7 @@ qemuDomainSetupLaunchSecurity(virDomainObj *vm,
 VIR_DEBUG("Set up launch security for SEV");
 break;
 case VIR_DOMAIN_LAUNCH_SECURITY_PV:
+case VIR_DOMAIN_LAUNCH_SECURITY_PAPR_PEF:
 case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
 break;
 case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 22f2278fcf..44951fd592 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -6705,6 +6705,7 @@ qemuProcessPrepareLaunchSecurityGuestInput(virDomainObj 
*vm)
 case VIR_DOMAIN_LAUNCH_SECURITY_SEV:
 return qemuProcessPrepareSEVGuestInput(vm, sec);
 case VIR_DOMAIN_LAUNCH_SECURITY_PV:
+case VIR_DOMAIN_LAUNCH_SECUR

[PATCH 0/5] Support for launchSecurity type papr-pef

2021-06-02 Thread Daniel Henrique Barboza
Hi,

This is the implementation of ppc64 secure guest execution, known
as PAPR-PEF. This implementation is based on the new
confidential-guest-support machine option that is available in
QEMU 6.0.0.

The patches were done on top of Boris s390-pv patches that were
sent by review [1] given that Boris provided a common base for
new security launches there.

The series is also available in gitlab:
https://gitlab.com/danielhb/libvirt/-/tree/papr_pef_v1



Note: If someone wishes to give this series a try, considering that you
have a host with proper PowerPC PEF hardware, be aware that there is
a QEMU bug in which launching a PAPR-PEF guest will trigger an early
assert [2]. The fix is not merged upstream at the moment of this
posting, so you'll need to apply the patch yourself or build
QEMU using David Gibson's ppc-for-6.1 tree [3].

[1] https://listman.redhat.com/archives/libvir-list/2021-May/msg00570.html
[2] https://lists.gnu.org/archive/html/qemu-devel/2021-05/msg08491.html
[3] https://gitlab.com/dgibson/qemu/-/tree/ppc-for-6.1

Daniel Henrique Barboza (5):
  tests: Add QEMU and domain ppc64 capapbilities for qemu 6.1
  qemu: add 'pef-guest' capability
  conf, qemu: add 'papr-pef' launch security type
  tests: add tests for 'papr-pef' support
  docs/formatdomain.rst: add 'papr-pef' launchSecurity docs

 docs/formatdomain.rst | 4 +
 docs/schemas/domaincommon.rng | 1 +
 src/conf/domain_conf.c| 3 +
 src/conf/domain_conf.h| 1 +
 src/qemu/qemu_capabilities.c  | 2 +
 src/qemu/qemu_capabilities.h  | 1 +
 src/qemu/qemu_command.c   |26 +
 src/qemu/qemu_namespace.c | 1 +
 src/qemu/qemu_process.c   | 1 +
 src/qemu/qemu_validate.c  | 8 +
 tests/domaincapsdata/qemu_6.1.0.ppc64.xml |   133 +
 .../launch-security-papr-pef.xml  |22 +
 tests/genericxml2xmltest.c| 1 +
 .../caps_6.1.0.ppc64.replies  | 30368 
 .../qemucapabilitiesdata/caps_6.1.0.ppc64.xml |  1175 +
 ...default-video-type-ppc64.ppc64-latest.args | 5 +-
 ...y-papr-pef-ignore-policy.ppc64-latest.args |30 +
 ...launch-security-papr-pef-ignore-policy.xml |19 +
 ...launch-security-papr-pef.ppc64-latest.args |30 +
 .../launch-security-papr-pef.xml  |16 +
 ...ault-cpu-kvm-pseries-2.7.ppc64-latest.args | 5 +-
 ...ault-cpu-kvm-pseries-3.1.ppc64-latest.args | 5 +-
 ...ault-cpu-kvm-pseries-4.2.ppc64-latest.args | 5 +-
 ...ault-cpu-tcg-pseries-2.7.ppc64-latest.args | 5 +-
 ...ault-cpu-tcg-pseries-3.1.ppc64-latest.args | 5 +-
 ...ault-cpu-tcg-pseries-4.2.ppc64-latest.args | 5 +-
 .../ppc64-pseries-graphics.ppc64-latest.args  | 7 +-
 .../ppc64-pseries-headless.ppc64-latest.args  | 7 +-
 .../ppc64-tpmproxy-single.ppc64-latest.args   | 5 +-
 .../ppc64-tpmproxy-with-tpm.ppc64-latest.args | 5 +-
 .../tpm-emulator-spapr.ppc64-latest.args  | 5 +-
 tests/qemuxml2argvtest.c  | 3 +
 32 files changed, 31871 insertions(+), 38 deletions(-)
 create mode 100644 tests/domaincapsdata/qemu_6.1.0.ppc64.xml
 create mode 100644 tests/genericxml2xmlindata/launch-security-papr-pef.xml
 create mode 100644 tests/qemucapabilitiesdata/caps_6.1.0.ppc64.replies
 create mode 100644 tests/qemucapabilitiesdata/caps_6.1.0.ppc64.xml
 create mode 100644 
tests/qemuxml2argvdata/launch-security-papr-pef-ignore-policy.ppc64-latest.args
 create mode 100644 
tests/qemuxml2argvdata/launch-security-papr-pef-ignore-policy.xml
 create mode 100644 
tests/qemuxml2argvdata/launch-security-papr-pef.ppc64-latest.args
 create mode 100644 tests/qemuxml2argvdata/launch-security-papr-pef.xml

-- 
2.31.1



Re: [PATCH 4/4] docs: add s390-pv documentation

2021-05-20 Thread Daniel Henrique Barboza




On 5/19/21 2:40 PM, Boris Fiuczynski wrote:

Add documentation for launch security type s390-pv.

Signed-off-by: Boris Fiuczynski 
---
  docs/formatdomain.rst  |  7 
  docs/kbase/s390_protected_virt.rst | 55 +-
  2 files changed, 54 insertions(+), 8 deletions(-)

diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst
index fa5c14febc..635fd5a55f 100644
--- a/docs/formatdomain.rst
+++ b/docs/formatdomain.rst
@@ -8044,6 +8044,13 @@ Note: DEA/TDEA is synonymous with DES/TDES.
  Launch Security
  ---
  
+Specifying  in an s390 VM prepares for

+running the guest in protected virtualization secure mode, also known as
+IBM Secure Execution. For more required host and guest preparation steps, see


The flow is a bit awkward here. Perhaps something like:


"Specifying  in a s390 domain prepares
the guest to run in protected virtualization secure mode, also known as
IBM Secure Execution.  (...)"


Other than that,


Reviewed-by: Daniel Henrique Barboza 




+`Protected Virtualization on s390 `__
+:since:`Since 7.4.0`
+
+
  The contents of the  element is used to provide
  the guest owners input used for creating an encrypted VM using the AMD SEV
  feature (Secure Encrypted Virtualization). SEV is an extension to the AMD-V
diff --git a/docs/kbase/s390_protected_virt.rst 
b/docs/kbase/s390_protected_virt.rst
index 1718a556d4..5c9ce0e21c 100644
--- a/docs/kbase/s390_protected_virt.rst
+++ b/docs/kbase/s390_protected_virt.rst
@@ -127,10 +127,13 @@ Protected virtualization guests support I/O using virtio 
devices.
  As the virtio data structures of secure guests are not accessible
  by the host, it is necessary to use shared memory ('bounce buffers').
  
-To enable virtio devices to use shared buffers, it is necessary

-to configure them with platform_iommu enabled. This can done by adding
-``iommu='on'`` to the driver element of a virtio device definition in the
-guest's XML, e.g.
+Since libvirt 7.4.0 the
+` <https://libvirt.org/formatdomain.html#launchSecurity>`__
+element with type ``s390-pv`` should be used on protected virtualization 
guests.
+Without ``launchSecurity`` you must enable all virtio devices to use shared
+buffers by configuring them with platform_iommu enabled.
+This can done by adding ``iommu='on'`` to the driver element of a virtio
+device definition in the guest's XML, e.g.
  
  ::
  
@@ -140,8 +143,10 @@ guest's XML, e.g.

   
 
  
-It is mandatory to define all virtio bus devices in this way to

-prevent the host from attempting to access protected memory.
+Unless you are using ``launchSecurity`` you must define all virtio bus
+devices in this way to prevent the host from attempting to access
+protected memory.
+
  Ballooning will not work and is fenced by QEMU. It should be
  disabled by specifying
  
@@ -158,8 +163,42 @@ allocated 2K entries. A commonly used value for swiotlb is 262144.

  Example guest definition
  
  
-Minimal domain XML for a protected virtualization guest, essentially

-it's mostly about the ``iommu`` property
+Minimal domain XML for a protected virtualization guest with
+the ``launchSecurity`` element of type ``s390-pv``
+
+::
+
+   
+ protected
+ 2048000
+ 2048000
+ 1
+ 
+   hvm
+ 
+ 
+ 
+   
+ 
+ 
+ 
+   
+   
+ 
+ 
+   
+   
+   
+ 
+ 
+   
+
+
+Example guest definition without launchSecurity
+===
+
+Minimal domain XML for a protected virtualization guest using the
+``iommu='on'`` setting for each virtio device.
  
  ::
  





Re: [PATCH 4/4] docs: add s390-pv documentation

2021-05-20 Thread Daniel Henrique Barboza




On 5/19/21 2:40 PM, Boris Fiuczynski wrote:

Add documentation for launch security type s390-pv.

Signed-off-by: Boris Fiuczynski 
---
  docs/formatdomain.rst  |  7 
  docs/kbase/s390_protected_virt.rst | 55 +-
  2 files changed, 54 insertions(+), 8 deletions(-)

diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst
index fa5c14febc..635fd5a55f 100644
--- a/docs/formatdomain.rst
+++ b/docs/formatdomain.rst
@@ -8044,6 +8044,13 @@ Note: DEA/TDEA is synonymous with DES/TDES.
  Launch Security
  ---
  
+Specifying  in an s390 VM prepares for

+running the guest in protected virtualization secure mode, also known as
+IBM Secure Execution. For more required host and guest preparation steps, see


The flow is a bit awkward here. Perhaps something like:


"Specifying  in a s390 domain prepares
the guest to run in protected virtualization secure mode, also known as
IBM Secure Execution.  (...)"


Other than that,


Reviewed-by: Daniel Henrique Barboza 




+`Protected Virtualization on s390 `__
+:since:`Since 7.4.0`
+
+
  The contents of the  element is used to provide
  the guest owners input used for creating an encrypted VM using the AMD SEV
  feature (Secure Encrypted Virtualization). SEV is an extension to the AMD-V
diff --git a/docs/kbase/s390_protected_virt.rst 
b/docs/kbase/s390_protected_virt.rst
index 1718a556d4..5c9ce0e21c 100644
--- a/docs/kbase/s390_protected_virt.rst
+++ b/docs/kbase/s390_protected_virt.rst
@@ -127,10 +127,13 @@ Protected virtualization guests support I/O using virtio 
devices.
  As the virtio data structures of secure guests are not accessible
  by the host, it is necessary to use shared memory ('bounce buffers').
  
-To enable virtio devices to use shared buffers, it is necessary

-to configure them with platform_iommu enabled. This can done by adding
-``iommu='on'`` to the driver element of a virtio device definition in the
-guest's XML, e.g.
+Since libvirt 7.4.0 the
+` <https://libvirt.org/formatdomain.html#launchSecurity>`__
+element with type ``s390-pv`` should be used on protected virtualization 
guests.
+Without ``launchSecurity`` you must enable all virtio devices to use shared
+buffers by configuring them with platform_iommu enabled.
+This can done by adding ``iommu='on'`` to the driver element of a virtio
+device definition in the guest's XML, e.g.
  
  ::
  
@@ -140,8 +143,10 @@ guest's XML, e.g.

   
 
  
-It is mandatory to define all virtio bus devices in this way to

-prevent the host from attempting to access protected memory.
+Unless you are using ``launchSecurity`` you must define all virtio bus
+devices in this way to prevent the host from attempting to access
+protected memory.
+
  Ballooning will not work and is fenced by QEMU. It should be
  disabled by specifying
  
@@ -158,8 +163,42 @@ allocated 2K entries. A commonly used value for swiotlb is 262144.

  Example guest definition
  
  
-Minimal domain XML for a protected virtualization guest, essentially

-it's mostly about the ``iommu`` property
+Minimal domain XML for a protected virtualization guest with
+the ``launchSecurity`` element of type ``s390-pv``
+
+::
+
+   
+ protected
+ 2048000
+ 2048000
+ 1
+ 
+   hvm
+ 
+ 
+ 
+   
+ 
+ 
+ 
+   
+   
+ 
+ 
+   
+   
+   
+ 
+ 
+   
+
+
+Example guest definition without launchSecurity
+===
+
+Minimal domain XML for a protected virtualization guest using the
+``iommu='on'`` setting for each virtio device.
  
  ::
  





Re: [PATCH 3/4] conf: add s390-pv as launch security type

2021-05-20 Thread Daniel Henrique Barboza




On 5/19/21 2:40 PM, Boris Fiuczynski wrote:

Add launch security type 's390-pv' as well as some tests.

Signed-off-by: Boris Fiuczynski 
---


Reviewed-by: Daniel Henrique Barboza 



  docs/schemas/domaincommon.rng |  1 +
  src/conf/domain_conf.c|  8 +
  src/conf/domain_conf.h|  1 +
  src/qemu/qemu_command.c   | 26 ++
  src/qemu/qemu_namespace.c |  1 +
  src/qemu/qemu_process.c   |  1 +
  src/qemu/qemu_validate.c  |  8 +
  .../launch-security-s390-pv-ignore-policy.xml | 24 +
  .../launch-security-s390-pv.xml   | 18 ++
  .../launch-security-s390-pv-ignore-policy.xml |  1 +
  tests/genericxml2xmltest.c|  2 ++
  ...ty-s390-pv-ignore-policy.s390x-latest.args | 35 +++
  .../launch-security-s390-pv-ignore-policy.xml | 33 +
  .../launch-security-s390-pv.s390x-latest.args | 35 +++
  .../launch-security-s390-pv.xml   | 30 
  tests/qemuxml2argvtest.c  |  3 ++
  16 files changed, 227 insertions(+)
  create mode 100644 
tests/genericxml2xmlindata/launch-security-s390-pv-ignore-policy.xml
  create mode 100644 tests/genericxml2xmlindata/launch-security-s390-pv.xml
  create mode 12 
tests/genericxml2xmloutdata/launch-security-s390-pv-ignore-policy.xml
  create mode 100644 
tests/qemuxml2argvdata/launch-security-s390-pv-ignore-policy.s390x-latest.args
  create mode 100644 
tests/qemuxml2argvdata/launch-security-s390-pv-ignore-policy.xml
  create mode 100644 
tests/qemuxml2argvdata/launch-security-s390-pv.s390x-latest.args
  create mode 100644 tests/qemuxml2argvdata/launch-security-s390-pv.xml

diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 3df13a0cf1..7c92e4c812 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -485,6 +485,7 @@

  
sev
+  s390-pv
  


diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 228de5d715..11ec8c8b0c 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -1393,6 +1393,7 @@ VIR_ENUM_IMPL(virDomainLaunchSecurity,
VIR_DOMAIN_LAUNCH_SECURITY_LAST,
"",
"sev",
+  "s390-pv",
  );
  
  static virClass *virDomainObjClass;

@@ -14762,6 +14763,8 @@ virDomainSecDefParseXML(xmlNodePtr lsecNode,
  if (!sec->sev)
  return NULL;
  break;
+case VIR_DOMAIN_LAUNCH_SECURITY_PV:
+break;
  case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
  case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
  default:
@@ -26896,6 +26899,11 @@ virDomainSecDefFormat(virBuffer *buf, virDomainSecDef 
*sec)
  break;
  }
  
+case VIR_DOMAIN_LAUNCH_SECURITY_PV:

+virBufferAsprintf(buf, "\n",
+  virDomainLaunchSecurityTypeToString(sec->sectype));
+break;
+
  case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
  case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
  break;
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index dd78f30ace..1d92065c7b 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -2631,6 +2631,7 @@ struct _virDomainKeyWrapDef {
  typedef enum {
  VIR_DOMAIN_LAUNCH_SECURITY_NONE,
  VIR_DOMAIN_LAUNCH_SECURITY_SEV,
+VIR_DOMAIN_LAUNCH_SECURITY_PV,
  
  VIR_DOMAIN_LAUNCH_SECURITY_LAST,

  } virDomainLaunchSecurity;
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 10dcf11d5b..67024f99b9 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -6992,6 +6992,9 @@ qemuBuildMachineCommandLine(virCommand *cmd,
  case VIR_DOMAIN_LAUNCH_SECURITY_SEV:
  virBufferAddLit(&buf, ",memory-encryption=sev0");
  break;
+case VIR_DOMAIN_LAUNCH_SECURITY_PV:
+virBufferAddLit(&buf, ",confidential-guest-support=pv0");
+break;
  case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
  break;
  case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
@@ -9879,6 +9882,26 @@ qemuBuildSEVCommandLine(virDomainObj *vm, virCommand 
*cmd,
  }
  
  
+static int

+qemuBuildPVCommandLine(virDomainObj *vm, virCommand *cmd)
+{
+g_autoptr(virJSONValue) props = NULL;
+g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER;
+qemuDomainObjPrivate *priv = vm->privateData;
+
+if (qemuMonitorCreateObjectProps(&props, "s390-pv-guest", "pv0",
+ NULL) < 0)
+return -1;
+
+if (qemuBuildObjectCommandlineFromJSON(&buf, props, priv->qemuCaps) < 0)
+return -1;
+
+virCommandAddArg(cmd, "-object");
+virCommandAddArgBuffer(cmd, &buf);
+return 0;
+

Re: [PATCH 3/4] conf: add s390-pv as launch security type

2021-05-20 Thread Daniel Henrique Barboza




On 5/20/21 12:10 PM, Boris Fiuczynski wrote:

On 5/20/21 2:08 PM, Daniel Henrique Barboza wrote:



On 5/20/21 4:05 AM, Boris Fiuczynski wrote:

On 5/19/21 9:34 PM, Daniel Henrique Barboza wrote:



On 5/19/21 2:40 PM, Boris Fiuczynski wrote:

Add launch security type 's390-pv' as well as some tests.

Signed-off-by: Boris Fiuczynski 
---
  docs/schemas/domaincommon.rng |  1 +
  src/conf/domain_conf.c    |  8 +
  src/conf/domain_conf.h    |  1 +
  src/qemu/qemu_command.c   | 26 ++
  src/qemu/qemu_namespace.c |  1 +
  src/qemu/qemu_process.c   |  1 +
  src/qemu/qemu_validate.c  |  8 +
  .../launch-security-s390-pv-ignore-policy.xml | 24 +
  .../launch-security-s390-pv.xml   | 18 ++
  .../launch-security-s390-pv-ignore-policy.xml |  1 +
  tests/genericxml2xmltest.c    |  2 ++
  ...ty-s390-pv-ignore-policy.s390x-latest.args | 35 +++
  .../launch-security-s390-pv-ignore-policy.xml | 33 +
  .../launch-security-s390-pv.s390x-latest.args | 35 +++
  .../launch-security-s390-pv.xml   | 30 
  tests/qemuxml2argvtest.c  |  3 ++
  16 files changed, 227 insertions(+)
  create mode 100644 
tests/genericxml2xmlindata/launch-security-s390-pv-ignore-policy.xml
  create mode 100644 tests/genericxml2xmlindata/launch-security-s390-pv.xml
  create mode 12 
tests/genericxml2xmloutdata/launch-security-s390-pv-ignore-policy.xml
  create mode 100644 
tests/qemuxml2argvdata/launch-security-s390-pv-ignore-policy.s390x-latest.args
  create mode 100644 
tests/qemuxml2argvdata/launch-security-s390-pv-ignore-policy.xml
  create mode 100644 
tests/qemuxml2argvdata/launch-security-s390-pv.s390x-latest.args
  create mode 100644 tests/qemuxml2argvdata/launch-security-s390-pv.xml

diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 3df13a0cf1..7c92e4c812 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -485,6 +485,7 @@
    
  
    sev
+  s390-pv
  
    
    


You added a new 's390-pv' security type, but down there you're using
the new confidential-guest-support feature from QEMU 6.0 which is also
valid for AMD and pSeries. I think you can do a little change in the idea
of these patches while keeping most of it. Instead of calling this new
support 's390-pv', call it 'confidential-guest-support' or 'CGS'.

My reasoning is that the QEMU community (namely David Gibson, qemu-ppc
maintainer) went into a lot of discussions back and forth to develop the
confidential-guest-support machine option, based on what was at first AMD-SEV
specific code, with the intention of make it easier for users to enable
secure guests across machine types. I believe Libvirt should follow suit
and do the same - a single option to enable secure guest supports for
all guests, with any differences in the support being handled by each arch
deep down in the driver.

Otherwise, what will end up happening is that when someone (probably myself)
come along with the secure guest support for pSeries (PEF), I will need to
create yet another launch type 'ppc64-pef' to do basically the same thing you're
already doing for s390x, which is adding '-machine 
confidential-guest-support=<>'
in the QEMU command line. Same thing with AMD SEV, and with any other
arch that QEMU might support with the confidential-guest-support option. We're
going to add extra XML parsing code and docs to handle the same thing.

Note that I'm not asking you to go ahead and implement the Libvirt support for
all the 3 archs. What I'm asking is to change the name of the launch security
type in the domain XML and docs to reflect that this will be the same type
that all other archs that has confidential-guest-support will end up using.


Thanks,


Daniel


Daniel,
thanks for your review and feedback.
When I looked at the QEMU commit 590466f056c4f
https://git.qemu.org/?p=qemu.git;a=commit;h=590466f056c4f2a7ff87ed751cece4f4ff02fd57
I did not get the impression that there is a common type for confidential guest 
support possible as the requiered data per type differs. Also I got the 
impression that the different types are not necessarily architecture bound. I 
may have gotten the wrong impression.



The point I tried to make is that, although there are different types of secure
VMs in QEMU, this doesn't mean that we need different launch security types in
Libvirt since they're all tied in the same QEMU machine option. If you check
the QEMU confidential-guest-support docs:

https://gitlab.com/qemu-project/qemu/-/blob/master/docs/confidential-guest-support.txt


To run a confidential guest you n

Re: [PATCH 3/4] conf: add s390-pv as launch security type

2021-05-20 Thread Daniel Henrique Barboza




On 5/20/21 4:05 AM, Boris Fiuczynski wrote:

On 5/19/21 9:34 PM, Daniel Henrique Barboza wrote:



On 5/19/21 2:40 PM, Boris Fiuczynski wrote:

Add launch security type 's390-pv' as well as some tests.

Signed-off-by: Boris Fiuczynski 
---
  docs/schemas/domaincommon.rng |  1 +
  src/conf/domain_conf.c    |  8 +
  src/conf/domain_conf.h    |  1 +
  src/qemu/qemu_command.c   | 26 ++
  src/qemu/qemu_namespace.c |  1 +
  src/qemu/qemu_process.c   |  1 +
  src/qemu/qemu_validate.c  |  8 +
  .../launch-security-s390-pv-ignore-policy.xml | 24 +
  .../launch-security-s390-pv.xml   | 18 ++
  .../launch-security-s390-pv-ignore-policy.xml |  1 +
  tests/genericxml2xmltest.c    |  2 ++
  ...ty-s390-pv-ignore-policy.s390x-latest.args | 35 +++
  .../launch-security-s390-pv-ignore-policy.xml | 33 +
  .../launch-security-s390-pv.s390x-latest.args | 35 +++
  .../launch-security-s390-pv.xml   | 30 
  tests/qemuxml2argvtest.c  |  3 ++
  16 files changed, 227 insertions(+)
  create mode 100644 
tests/genericxml2xmlindata/launch-security-s390-pv-ignore-policy.xml
  create mode 100644 tests/genericxml2xmlindata/launch-security-s390-pv.xml
  create mode 12 
tests/genericxml2xmloutdata/launch-security-s390-pv-ignore-policy.xml
  create mode 100644 
tests/qemuxml2argvdata/launch-security-s390-pv-ignore-policy.s390x-latest.args
  create mode 100644 
tests/qemuxml2argvdata/launch-security-s390-pv-ignore-policy.xml
  create mode 100644 
tests/qemuxml2argvdata/launch-security-s390-pv.s390x-latest.args
  create mode 100644 tests/qemuxml2argvdata/launch-security-s390-pv.xml

diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 3df13a0cf1..7c92e4c812 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -485,6 +485,7 @@
    
  
    sev
+  s390-pv
  
    
    


You added a new 's390-pv' security type, but down there you're using
the new confidential-guest-support feature from QEMU 6.0 which is also
valid for AMD and pSeries. I think you can do a little change in the idea
of these patches while keeping most of it. Instead of calling this new
support 's390-pv', call it 'confidential-guest-support' or 'CGS'.

My reasoning is that the QEMU community (namely David Gibson, qemu-ppc
maintainer) went into a lot of discussions back and forth to develop the
confidential-guest-support machine option, based on what was at first AMD-SEV
specific code, with the intention of make it easier for users to enable
secure guests across machine types. I believe Libvirt should follow suit
and do the same - a single option to enable secure guest supports for
all guests, with any differences in the support being handled by each arch
deep down in the driver.

Otherwise, what will end up happening is that when someone (probably myself)
come along with the secure guest support for pSeries (PEF), I will need to
create yet another launch type 'ppc64-pef' to do basically the same thing you're
already doing for s390x, which is adding '-machine 
confidential-guest-support=<>'
in the QEMU command line. Same thing with AMD SEV, and with any other
arch that QEMU might support with the confidential-guest-support option. We're
going to add extra XML parsing code and docs to handle the same thing.

Note that I'm not asking you to go ahead and implement the Libvirt support for
all the 3 archs. What I'm asking is to change the name of the launch security
type in the domain XML and docs to reflect that this will be the same type
that all other archs that has confidential-guest-support will end up using.


Thanks,


Daniel


Daniel,
thanks for your review and feedback.
When I looked at the QEMU commit 590466f056c4f
https://git.qemu.org/?p=qemu.git;a=commit;h=590466f056c4f2a7ff87ed751cece4f4ff02fd57
I did not get the impression that there is a common type for confidential guest 
support possible as the requiered data per type differs. Also I got the 
impression that the different types are not necessarily architecture bound. I 
may have gotten the wrong impression.



The point I tried to make is that, although there are different types of secure
VMs in QEMU, this doesn't mean that we need different launch security types in
Libvirt since they're all tied in the same QEMU machine option. If you check
the QEMU confidential-guest-support docs:

https://gitlab.com/qemu-project/qemu/-/blob/master/docs/confidential-guest-support.txt


To run a confidential guest you need to add two command line parameters:

1. Use "-object" to create a "confidential guest s

Re: [PATCH 3/4] conf: add s390-pv as launch security type

2021-05-19 Thread Daniel Henrique Barboza




On 5/19/21 4:34 PM, Daniel Henrique Barboza wrote:



On 5/19/21 2:40 PM, Boris Fiuczynski wrote:

Add launch security type 's390-pv' as well as some tests.

Signed-off-by: Boris Fiuczynski 
---
  docs/schemas/domaincommon.rng |  1 +
  src/conf/domain_conf.c    |  8 +
  src/conf/domain_conf.h    |  1 +
  src/qemu/qemu_command.c   | 26 ++
  src/qemu/qemu_namespace.c |  1 +
  src/qemu/qemu_process.c   |  1 +
  src/qemu/qemu_validate.c  |  8 +
  .../launch-security-s390-pv-ignore-policy.xml | 24 +
  .../launch-security-s390-pv.xml   | 18 ++
  .../launch-security-s390-pv-ignore-policy.xml |  1 +
  tests/genericxml2xmltest.c    |  2 ++
  ...ty-s390-pv-ignore-policy.s390x-latest.args | 35 +++
  .../launch-security-s390-pv-ignore-policy.xml | 33 +
  .../launch-security-s390-pv.s390x-latest.args | 35 +++
  .../launch-security-s390-pv.xml   | 30 
  tests/qemuxml2argvtest.c  |  3 ++
  16 files changed, 227 insertions(+)
  create mode 100644 
tests/genericxml2xmlindata/launch-security-s390-pv-ignore-policy.xml
  create mode 100644 tests/genericxml2xmlindata/launch-security-s390-pv.xml
  create mode 12 
tests/genericxml2xmloutdata/launch-security-s390-pv-ignore-policy.xml
  create mode 100644 
tests/qemuxml2argvdata/launch-security-s390-pv-ignore-policy.s390x-latest.args
  create mode 100644 
tests/qemuxml2argvdata/launch-security-s390-pv-ignore-policy.xml
  create mode 100644 
tests/qemuxml2argvdata/launch-security-s390-pv.s390x-latest.args
  create mode 100644 tests/qemuxml2argvdata/launch-security-s390-pv.xml

diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 3df13a0cf1..7c92e4c812 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -485,6 +485,7 @@
    
  
    sev
+  s390-pv
  
    
    


You added a new 's390-pv' security type, but down there you're using
the new confidential-guest-support feature from QEMU 6.0 which is also
valid for AMD and pSeries. I think you can do a little change in the idea
of these patches while keeping most of it. Instead of calling this new
support 's390-pv', call it 'confidential-guest-support' or 'CGS'.

My reasoning is that the QEMU community (namely David Gibson, qemu-ppc
maintainer) went into a lot of discussions back and forth to develop the
confidential-guest-support machine option, based on what was at first AMD-SEV
specific code, with the intention of make it easier for users to enable
secure guests across machine types. I believe Libvirt should follow suit
and do the same - a single option to enable secure guest supports for
all guests, with any differences in the support being handled by each arch
deep down in the driver.

Otherwise, what will end up happening is that when someone (probably myself)
come along with the secure guest support for pSeries (PEF), I will need to
create yet another launch type 'ppc64-pef' to do basically the same thing you're
already doing for s390x, which is adding '-machine 
confidential-guest-support=<>'
in the QEMU command line. Same thing with AMD SEV, and with any other
arch that QEMU might support with the confidential-guest-support option. We're
going to add extra XML parsing code and docs to handle the same thing.

Note that I'm not asking you to go ahead and implement the Libvirt support for
all the 3 archs. What I'm asking is to change the name of the launch security
type in the domain XML and docs to reflect that this will be the same type
that all other archs that has confidential-guest-support will end up using.




Just remembered that there's an open bug related to the generic
confidential-guest-support implementation in Libvirt like I mentioned
above:


https://bugzilla.redhat.com/show_bug.cgi?id=1961032



Pavel, CCing you since you're the current assignee of the bug.




Daniel






Thanks,


Daniel






diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 228de5d715..11ec8c8b0c 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -1393,6 +1393,7 @@ VIR_ENUM_IMPL(virDomainLaunchSecurity,
    VIR_DOMAIN_LAUNCH_SECURITY_LAST,
    "",
    "sev",
+  "s390-pv",
  );
  static virClass *virDomainObjClass;
@@ -14762,6 +14763,8 @@ virDomainSecDefParseXML(xmlNodePtr lsecNode,
  if (!sec->sev)
  return NULL;
  break;
+    case VIR_DOMAIN_LAUNCH_SECURITY_PV:
+    break;
  case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
  case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
  default:
@@ -26

Re: [PATCH 3/4] conf: add s390-pv as launch security type

2021-05-19 Thread Daniel Henrique Barboza




On 5/19/21 2:40 PM, Boris Fiuczynski wrote:

Add launch security type 's390-pv' as well as some tests.

Signed-off-by: Boris Fiuczynski 
---
  docs/schemas/domaincommon.rng |  1 +
  src/conf/domain_conf.c|  8 +
  src/conf/domain_conf.h|  1 +
  src/qemu/qemu_command.c   | 26 ++
  src/qemu/qemu_namespace.c |  1 +
  src/qemu/qemu_process.c   |  1 +
  src/qemu/qemu_validate.c  |  8 +
  .../launch-security-s390-pv-ignore-policy.xml | 24 +
  .../launch-security-s390-pv.xml   | 18 ++
  .../launch-security-s390-pv-ignore-policy.xml |  1 +
  tests/genericxml2xmltest.c|  2 ++
  ...ty-s390-pv-ignore-policy.s390x-latest.args | 35 +++
  .../launch-security-s390-pv-ignore-policy.xml | 33 +
  .../launch-security-s390-pv.s390x-latest.args | 35 +++
  .../launch-security-s390-pv.xml   | 30 
  tests/qemuxml2argvtest.c  |  3 ++
  16 files changed, 227 insertions(+)
  create mode 100644 
tests/genericxml2xmlindata/launch-security-s390-pv-ignore-policy.xml
  create mode 100644 tests/genericxml2xmlindata/launch-security-s390-pv.xml
  create mode 12 
tests/genericxml2xmloutdata/launch-security-s390-pv-ignore-policy.xml
  create mode 100644 
tests/qemuxml2argvdata/launch-security-s390-pv-ignore-policy.s390x-latest.args
  create mode 100644 
tests/qemuxml2argvdata/launch-security-s390-pv-ignore-policy.xml
  create mode 100644 
tests/qemuxml2argvdata/launch-security-s390-pv.s390x-latest.args
  create mode 100644 tests/qemuxml2argvdata/launch-security-s390-pv.xml

diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 3df13a0cf1..7c92e4c812 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -485,6 +485,7 @@

  
sev
+  s390-pv
  




You added a new 's390-pv' security type, but down there you're using
the new confidential-guest-support feature from QEMU 6.0 which is also
valid for AMD and pSeries. I think you can do a little change in the idea
of these patches while keeping most of it. Instead of calling this new
support 's390-pv', call it 'confidential-guest-support' or 'CGS'.

My reasoning is that the QEMU community (namely David Gibson, qemu-ppc
maintainer) went into a lot of discussions back and forth to develop the
confidential-guest-support machine option, based on what was at first AMD-SEV
specific code, with the intention of make it easier for users to enable
secure guests across machine types. I believe Libvirt should follow suit
and do the same - a single option to enable secure guest supports for
all guests, with any differences in the support being handled by each arch
deep down in the driver.

Otherwise, what will end up happening is that when someone (probably myself)
come along with the secure guest support for pSeries (PEF), I will need to
create yet another launch type 'ppc64-pef' to do basically the same thing you're
already doing for s390x, which is adding '-machine 
confidential-guest-support=<>'
in the QEMU command line. Same thing with AMD SEV, and with any other
arch that QEMU might support with the confidential-guest-support option. We're
going to add extra XML parsing code and docs to handle the same thing.

Note that I'm not asking you to go ahead and implement the Libvirt support for
all the 3 archs. What I'm asking is to change the name of the launch security
type in the domain XML and docs to reflect that this will be the same type
that all other archs that has confidential-guest-support will end up using.


Thanks,


Daniel






diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 228de5d715..11ec8c8b0c 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -1393,6 +1393,7 @@ VIR_ENUM_IMPL(virDomainLaunchSecurity,
VIR_DOMAIN_LAUNCH_SECURITY_LAST,
"",
"sev",
+  "s390-pv",
  );
  
  static virClass *virDomainObjClass;

@@ -14762,6 +14763,8 @@ virDomainSecDefParseXML(xmlNodePtr lsecNode,
  if (!sec->sev)
  return NULL;
  break;
+case VIR_DOMAIN_LAUNCH_SECURITY_PV:
+break;
  case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
  case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
  default:
@@ -26896,6 +26899,11 @@ virDomainSecDefFormat(virBuffer *buf, virDomainSecDef 
*sec)
  break;
  }
  
+case VIR_DOMAIN_LAUNCH_SECURITY_PV:

+virBufferAsprintf(buf, "\n",
+  virDomainLaunchSecurityTypeToString(sec->sectype));
+break;
+
  case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
  case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
  break;
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index dd78f30ace..1d92065c7b 1006

Re: [PATCH 2/4] qemu: add s390-pv-guest capability

2021-05-19 Thread Daniel Henrique Barboza




On 5/19/21 2:40 PM, Boris Fiuczynski wrote:

Add s390-pv-guest capability.

Signed-off-by: Boris Fiuczynski 
---


Reviewed-by: Daniel Henrique Barboza 


  src/qemu/qemu_capabilities.c| 2 ++
  src/qemu/qemu_capabilities.h| 1 +
  tests/qemucapabilitiesdata/caps_6.0.0.s390x.xml | 1 +
  3 files changed, 4 insertions(+)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index d3f24feb6a..3d0b552f62 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -629,6 +629,7 @@ VIR_ENUM_IMPL(virQEMUCaps,
/* 400 */
"compat-deprecated",
"acpi-index",
+  "s390-pv-guest",
  );
  
  
@@ -1347,6 +1348,7 @@ struct virQEMUCapsStringFlags virQEMUCapsObjectTypes[] = {

  { "am53c974", QEMU_CAPS_SCSI_AM53C974 },
  { "virtio-pmem-pci", QEMU_CAPS_DEVICE_VIRTIO_PMEM_PCI },
  { "vhost-user-blk", QEMU_CAPS_DEVICE_VHOST_USER_BLK },
+{ "s390-pv-guest", QEMU_CAPS_S390_PV_GUEST },
  };
  
  
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h

index fae8492e69..b76798501b 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -609,6 +609,7 @@ typedef enum { /* virQEMUCapsFlags grouping marker for 
syntax-check */
  /* 400 */
  QEMU_CAPS_COMPAT_DEPRECATED, /* -compat deprecated-(input|output) is 
supported */
  QEMU_CAPS_ACPI_INDEX, /* PCI device 'acpi-index' property */
+QEMU_CAPS_S390_PV_GUEST, /* -object s390-pv-guest,... */
  
  QEMU_CAPS_LAST /* this must always be the last item */

  } virQEMUCapsFlags;
diff --git a/tests/qemucapabilitiesdata/caps_6.0.0.s390x.xml 
b/tests/qemucapabilitiesdata/caps_6.0.0.s390x.xml
index 4c056c484f..2f840073bc 100644
--- a/tests/qemucapabilitiesdata/caps_6.0.0.s390x.xml
+++ b/tests/qemucapabilitiesdata/caps_6.0.0.s390x.xml
@@ -164,6 +164,7 @@



+  
600
0
39100242





Re: [PATCH 1/4] conf: refactor launch security to allow more types

2021-05-19 Thread Daniel Henrique Barboza




On 5/19/21 2:40 PM, Boris Fiuczynski wrote:

To allow other types of launch security the SEV type specific
parameters like e.g. policy need to be optional and be separated
from other new launch security types.
A test is added to ensure the previously required and now optional
launch security policy remains required when launch security type
is SEV.



I think you missed a breakline up there.


Reviewed-by: Daniel Henrique Barboza 


Signed-off-by: Boris Fiuczynski 
---
  docs/schemas/domaincommon.rng |  12 +-
  src/conf/domain_conf.c| 156 +++---
  src/conf/domain_conf.h|  13 +-
  src/conf/virconftypes.h   |   2 +
  src/qemu/qemu_cgroup.c|   4 +-
  src/qemu/qemu_command.c   |  38 -
  src/qemu/qemu_driver.c|   2 +-
  src/qemu/qemu_firmware.c  |   4 +-
  src/qemu/qemu_namespace.c |  20 ++-
  src/qemu/qemu_process.c   |  35 +++-
  src/qemu/qemu_validate.c  |  22 ++-
  src/security/security_dac.c   |   4 +-
  ...urity-sev-missing-policy.x86_64-2.12.0.err |   1 +
  .../launch-security-sev-missing-policy.xml|  34 
  tests/qemuxml2argvtest.c  |   1 +
  15 files changed, 253 insertions(+), 95 deletions(-)
  create mode 100644 
tests/qemuxml2argvdata/launch-security-sev-missing-policy.x86_64-2.12.0.err
  create mode 100644 
tests/qemuxml2argvdata/launch-security-sev-missing-policy.xml

diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index a2e5c50c1d..3df13a0cf1 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -483,7 +483,9 @@

  

-sev
+
+  sev
+


  
@@ -496,9 +498,11 @@
  

  
-
-  
-
+
+  
+
+  
+
  

  
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index b3ed3a9c5a..228de5d715 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -3481,8 +3481,7 @@ virDomainResctrlDefFree(virDomainResctrlDef *resctrl)
  }
  
  
-static void

-virDomainSEVDefFree(virDomainSEVDef *def)
+void virDomainSEVDefFree(virDomainSEVDef *def)
  {
  if (!def)
  return;
@@ -3493,6 +3492,17 @@ virDomainSEVDefFree(virDomainSEVDef *def)
  g_free(def);
  }
  
+void virDomainSecDefFree(virDomainSecDef *def)

+{
+if (!def)
+return;
+
+virDomainSEVDefFree(def->sev);
+
+g_free(def);
+}
+
+
  static void
  virDomainOSDefClear(virDomainOSDef *os)
  {
@@ -3694,7 +3704,7 @@ void virDomainDefFree(virDomainDef *def)
  if (def->namespaceData && def->ns.free)
  (def->ns.free)(def->namespaceData);
  
-virDomainSEVDefFree(def->sev);

+virDomainSecDefFree(def->sec);
  
  xmlFreeNode(def->metadata);
  
@@ -14688,72 +14698,80 @@ virDomainSEVDefParseXML(xmlNodePtr sevNode,

  xmlXPathContextPtr ctxt)
  {
  VIR_XPATH_NODE_AUTORESTORE(ctxt)
-virDomainSEVDef *def;
+g_autoptr(virDomainSEVDef) sev = g_new0(virDomainSEVDef, 1);
  unsigned long policy;
-g_autofree char *type = NULL;
  int rc = -1;
  
-def = g_new0(virDomainSEVDef, 1);

-
  ctxt->node = sevNode;
  
-if (!(type = virXMLPropString(sevNode, "type"))) {

-virReportError(VIR_ERR_XML_ERROR, "%s",
-   _("missing launch security type"));
-goto error;
-}
-
-def->sectype = virDomainLaunchSecurityTypeFromString(type);
-switch ((virDomainLaunchSecurity) def->sectype) {
-case VIR_DOMAIN_LAUNCH_SECURITY_SEV:
-break;
-case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
-case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
-default:
-virReportError(VIR_ERR_XML_ERROR,
-   _("unsupported launch security type '%s'"),
-   type);
-goto error;
-}
-
  if (virXPathULongHex("string(./policy)", ctxt, &policy) < 0) {
  virReportError(VIR_ERR_XML_ERROR, "%s",
-   _("failed to get launch security policy"));
-goto error;
+   _("Failed to get launch security policy for "
+ "launch security type SEV"));
+return NULL;
  }
  
  /* the following attributes are platform dependent and if missing, we can

   * autofill them from domain capabilities later
   */
-rc = virXPathUInt("string(./cbitpos)", ctxt, &def->cbitpos);
+rc = virXPathUInt("string(./cbitpos)", ctxt, &sev->cbitpos);
  if (rc == 0) {
-def->haveCbitpos = true

Re: [PATCH v2] libxl: set vcpu affinity during domain creation

2021-05-10 Thread Daniel Henrique Barboza




On 5/5/21 11:06 AM, Olaf Hering wrote:

Since Xen 4.5 libxl allows to set affinities during domain creation.
This enables Xen to allocate the domain memory on NUMA systems close to
the specified pcpus.

Libvirt can now handle  in domU.xml correctly.

Without this change, Xen will create the domU and assign NUMA memory and
vcpu affinities on its own. Later libvirt will adjust the affinity,
which may move the vcpus away from the assigned NUMA node.

Signed-off-by: Olaf Hering 
---


Reviewed-by: Daniel Henrique Barboza 


  src/libxl/libxl_conf.c   | 53 
  src/libxl/libxl_domain.c | 46 --
  src/libxl/libxl_domain.h |  4 ---
  3 files changed, 53 insertions(+), 50 deletions(-)

diff --git a/src/libxl/libxl_conf.c b/src/libxl/libxl_conf.c
index 6392d7795d..2a99626f92 100644
--- a/src/libxl/libxl_conf.c
+++ b/src/libxl/libxl_conf.c
@@ -283,6 +283,56 @@ libxlMakeChrdevStr(virDomainChrDef *def, char **buf)
  return 0;
  }
  
+static int

+libxlSetVcpuAffinities(virDomainDef *def,
+   libxl_ctx *ctx,
+   libxl_domain_build_info *b_info)
+{
+libxl_bitmap *vcpu_affinity_array;
+unsigned int vcpuid;
+unsigned int vcpu_idx = 0;
+virDomainVcpuDef *vcpu;
+bool has_vcpu_pin = false;
+
+/* Get highest vcpuid with cpumask */
+for (vcpuid = 0; vcpuid < b_info->max_vcpus; vcpuid++) {
+vcpu = virDomainDefGetVcpu(def, vcpuid);
+if (!vcpu)
+continue;
+if (!vcpu->cpumask)
+continue;
+vcpu_idx = vcpuid;
+has_vcpu_pin = true;
+}
+/* Nothing to do */
+if (!has_vcpu_pin)
+return 0;
+
+/* Adjust index */
+vcpu_idx++;
+
+b_info->num_vcpu_hard_affinity = vcpu_idx;
+/* Will be released by libxl_domain_config_dispose */
+b_info->vcpu_hard_affinity = g_new0(libxl_bitmap, vcpu_idx);
+vcpu_affinity_array = b_info->vcpu_hard_affinity;
+
+for (vcpuid = 0; vcpuid < vcpu_idx; vcpuid++) {
+libxl_bitmap *map = &vcpu_affinity_array[vcpuid];
+libxl_bitmap_init(map);
+/* libxl owns the bitmap */
+if (libxl_cpu_bitmap_alloc(ctx, map, 0))
+return -1;
+vcpu = virDomainDefGetVcpu(def, vcpuid);
+/* Apply the given mask, or allow unhandled vcpus to run anywhere */
+if (vcpu && vcpu->cpumask)
+virBitmapToDataBuf(vcpu->cpumask, map->map, map->size);
+else
+libxl_bitmap_set_any(map);
+}
+libxl_defbool_set(&b_info->numa_placement, false);
+return 0;
+}
+
  static int
  libxlMakeDomBuildInfo(virDomainDef *def,
libxlDriverConfig *cfg,
@@ -320,6 +370,9 @@ libxlMakeDomBuildInfo(virDomainDef *def,
  for (i = 0; i < virDomainDefGetVcpus(def); i++)
  libxl_bitmap_set((&b_info->avail_vcpus), i);
  
+if (libxlSetVcpuAffinities(def, ctx, b_info))

+return -1;
+
  switch ((virDomainClockOffsetType) clock.offset) {
  case VIR_DOMAIN_CLOCK_OFFSET_VARIABLE:
  if (clock.data.variable.basis == VIR_DOMAIN_CLOCK_BASIS_LOCALTIME)
diff --git a/src/libxl/libxl_domain.c b/src/libxl/libxl_domain.c
index d78765ad84..625e04a9b0 100644
--- a/src/libxl/libxl_domain.c
+++ b/src/libxl/libxl_domain.c
@@ -967,49 +967,6 @@ libxlDomainAutoCoreDump(libxlDriverPrivate *driver,
  return 0;
  }
  
-int

-libxlDomainSetVcpuAffinities(libxlDriverPrivate *driver, virDomainObj *vm)
-{
-g_autoptr(libxlDriverConfig) cfg = libxlDriverConfigGet(driver);
-virDomainVcpuDef *vcpu;
-libxl_bitmap map;
-virBitmap *cpumask = NULL;
-size_t i;
-int ret = -1;
-
-libxl_bitmap_init(&map);
-
-for (i = 0; i < virDomainDefGetVcpus(vm->def); ++i) {
-vcpu = virDomainDefGetVcpu(vm->def, i);
-
-if (!vcpu->online)
-continue;
-
-if (!(cpumask = vcpu->cpumask))
-cpumask = vm->def->cpumask;
-
-if (!cpumask)
-continue;
-
-if (virBitmapToData(cpumask, &map.map, (int *)&map.size) < 0)
-goto cleanup;
-
-if (libxl_set_vcpuaffinity(cfg->ctx, vm->def->id, i, &map, NULL) != 0) 
{
-virReportError(VIR_ERR_INTERNAL_ERROR,
-   _("Failed to pin vcpu '%zu' with libxenlight"), i);
-goto cleanup;
-}
-
-libxl_bitmap_dispose(&map); /* Also returns to freshly-init'd state */
-}
-
-ret = 0;
-
- cleanup:
-libxl_bitmap_dispose(&map);
-return ret;
-}
-
  static int
  libxlDomainFreeMem(libxl_ctx *ctx, libxl_domain_config *d_config)
  {
@@ -1460,9 +1417,6 @@ libxlDomainStart(libxlDriverPrivate *driver,
  goto destroy_dom;
  }
  
-if (libxlDomainSetVcpuAffinities(driver, vm) < 0)

-goto destroy_dom;
-
  if (!start_paused) {
  lib

Re: [PATCH] vbox: Make host CPU cache init non-fatal

2021-04-15 Thread Daniel Henrique Barboza




On 4/8/21 3:15 PM, Charlie Sharpsteen wrote:

This commit updates the vbox driver to log a warning if the
virCapabilitiesInitCaches function fails instead of treating failure
as a fatal error. CPU cache initialization requires the sysfs filesystem
in order to complete successfully and thus fails on platforms such as macOS.

This commit is similar to ace6528ae19, which made the same change to the
VMware driver.

Signed-off-by: Charlie Sharpsteen 
---


Looks reasonable to me.


Reviewed-by: Daniel Henrique Barboza 



  src/vbox/vbox_common.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/vbox/vbox_common.c b/src/vbox/vbox_common.c
index 5a5de85eab..933851346b 100644
--- a/src/vbox/vbox_common.c
+++ b/src/vbox/vbox_common.c
@@ -98,7 +98,7 @@ vboxCapsInit(void)
  return NULL;
  
  if (virCapabilitiesInitCaches(caps) < 0)

-return NULL;
+VIR_WARN("Failed to get host CPU cache info");
  
  if ((guest = virCapabilitiesAddGuest(caps,

   VIR_DOMAIN_OSTYPE_HVM,





Re: [libvirt PATCH 4/4] qemu: increase locked memory limit when a vDPA device is present

2021-03-24 Thread Daniel Henrique Barboza




On 3/23/21 3:50 PM, Laine Stump wrote:

Just like VFIO devices, vDPA devices may need to have all guest memory
pages locked/pinned in order to operate properly. In the case of VFIO
devices (including mdev and NVME, which also use VFIO) libvirt
automatically increases the locked memory limit when one of those
devices is present. This patch modifies that code to also increase the
limit if there are any vDPA devices present.

Resolves: https://bugzilla.redhat.com/1939776
Signed-off-by: Laine Stump 
---


Reviewed-by: Daniel Henrique Barboza 


  src/qemu/qemu_domain.c | 4 ++--
  1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index e0379e81ba..76e8903dbc 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -9199,7 +9199,7 @@ getPPC64MemLockLimitBytes(virDomainDefPtr def,
  passthroughLimit = maxMemory +
 128 * (1ULL<<30) / 512 * nPCIHostBridges +
 8192;
-} else if (forceVFIO || qemuDomainNeedsVFIO(def)) {
+} else if (forceVFIO || qemuDomainNeedsVFIO(def) || 
virDomainDefHasVDPANet(def)) {
  /* For regular (non-NVLink2 present) VFIO passthrough, the value
   * of passthroughLimit is:
   *
@@ -9289,7 +9289,7 @@ qemuDomainGetMemLockLimitBytes(virDomainDefPtr def,
   *
   * Note that this may not be valid for all platforms.
   */
-if (forceVFIO || qemuDomainNeedsVFIO(def))
+if (forceVFIO || qemuDomainNeedsVFIO(def) || virDomainDefHasVDPANet(def))
  memKB = virDomainDefGetMemoryTotal(def) + 1024 * 1024;
  
  return memKB << 10;






Re: [libvirt PATCH 3/4] qemu: account for mdev devices in getPPC64MemLockLimitBytes()

2021-03-24 Thread Daniel Henrique Barboza




On 3/23/21 3:50 PM, Laine Stump wrote:

This function is a specialized version of
qemuDomainGetMemLockLimitBytes() for PPC64. Simplifying it in the same
manner as the previous patch has the nice side effect of accounting
for the possibility of an mdev device in the config.

(I don't know if mdev devices are supported on PPC, but even if not
then a) the additional check for mdev devices gained by using
qemuDomainNeedsVFIO() in place of open coding will be an effective
NOP, and b) if mdev devices are supported on PPC64 in the future, this
function will be prepared for it).


PowerPC guest does not support mdev. I agree that there is no harm in
considering that this might change in the future though. One less piece
of code to change is always welcome.

Reviewed-by: Daniel Henrique Barboza 



Signed-off-by: Laine Stump 
---
  src/qemu/qemu_domain.c | 9 ++---
  1 file changed, 2 insertions(+), 7 deletions(-)

diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 5238a52095..e0379e81ba 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -9122,7 +9122,6 @@ getPPC64MemLockLimitBytes(virDomainDefPtr def,
  unsigned long long passthroughLimit = 0;
  size_t i, nPCIHostBridges = 0;
  virPCIDeviceAddressPtr pciAddr;
-bool usesVFIO = false;
  bool nvlink2Capable = false;
  
  for (i = 0; i < def->ncontrollers; i++) {

@@ -9138,7 +9137,6 @@ getPPC64MemLockLimitBytes(virDomainDefPtr def,
  virDomainHostdevDefPtr dev = def->hostdevs[i];
  
  if (virHostdevIsVFIODevice(dev)) {

-usesVFIO = true;
  
  pciAddr = &dev->source.subsys.u.pci.addr;

  if (virPCIDeviceAddressIsValid(pciAddr, false)) {
@@ -9153,9 +9151,6 @@ getPPC64MemLockLimitBytes(virDomainDefPtr def,
  }
  }
  
-if (virDomainDefHasNVMeDisk(def))

-usesVFIO = true;
-
  memory = virDomainDefGetMemoryTotal(def);
  
  if (def->mem.max_memory)

@@ -9180,7 +9175,7 @@ getPPC64MemLockLimitBytes(virDomainDefPtr def,
  8192;
  
  /* NVLink2 support in QEMU is a special case of the passthrough

- * mechanics explained in the usesVFIO case below. The GPU RAM
+ * mechanics explained in the forceVFIO case below. The GPU RAM
   * is placed with a gap after maxMemory. The current QEMU
   * implementation puts the NVIDIA RAM above the PCI MMIO, which
   * starts at 32TiB and is the MMIO reserved for the guest main RAM.
@@ -9204,7 +9199,7 @@ getPPC64MemLockLimitBytes(virDomainDefPtr def,
  passthroughLimit = maxMemory +
 128 * (1ULL<<30) / 512 * nPCIHostBridges +
 8192;
-} else if (usesVFIO || forceVFIO) {
+} else if (forceVFIO || qemuDomainNeedsVFIO(def)) {
  /* For regular (non-NVLink2 present) VFIO passthrough, the value
   * of passthroughLimit is:
   *





Re: [libvirt PATCH 2/4] qemu: simplify qemuDomainGetMemLockLimitBytes()

2021-03-24 Thread Daniel Henrique Barboza




On 3/23/21 3:50 PM, Laine Stump wrote:

This function goes through a loop checking if each hostdev is a VFIO
or mdev device, and then later it calls virDomainDefHasNVMEDisk(). The
function qemuDomainNeedsVFIO() does exactly the same thing, so let's
just call that instead.

Signed-off-by: Laine Stump 
---


Reviewed-by: Daniel Henrique Barboza 



  src/qemu/qemu_domain.c | 17 +
  1 file changed, 1 insertion(+), 16 deletions(-)

diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 5f0c7f0531..5238a52095 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -9258,8 +9258,6 @@ qemuDomainGetMemLockLimitBytes(virDomainDefPtr def,
 bool forceVFIO)
  {
  unsigned long long memKB = 0;
-bool usesVFIO = false;
-size_t i;
  
  /* prefer the hard limit */

  if (virMemoryLimitIsSet(def->mem.hard_limit)) {
@@ -9296,20 +9294,7 @@ qemuDomainGetMemLockLimitBytes(virDomainDefPtr def,
   *
   * Note that this may not be valid for all platforms.
   */
-if (!forceVFIO) {
-for (i = 0; i < def->nhostdevs; i++) {
-if (virHostdevIsVFIODevice(def->hostdevs[i]) ||
-virHostdevIsMdevDevice(def->hostdevs[i])) {
-usesVFIO = true;
-break;
-}
-}
-
-if (virDomainDefHasNVMeDisk(def))
-usesVFIO = true;
-}
-
-if (usesVFIO || forceVFIO)
+if (forceVFIO || qemuDomainNeedsVFIO(def))
  memKB = virDomainDefGetMemoryTotal(def) + 1024 * 1024;
  
  return memKB << 10;






Re: [libvirt PATCH 1/4] conf: new function virDomainDefHasVDPANet()

2021-03-24 Thread Daniel Henrique Barboza




On 3/23/21 3:50 PM, Laine Stump wrote:

This function returns true if the domain has any interfaces that are
type='vdpa'.

Signed-off-by: Laine Stump 
---


Reviewed-by: Daniel Henrique Barboza 


  src/conf/domain_conf.c   | 14 ++
  src/conf/domain_conf.h   |  3 +++
  src/libvirt_private.syms |  1 +
  3 files changed, 18 insertions(+)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index f071bf93d0..736e9de3c8 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -32500,6 +32500,20 @@ virDomainDefHasMdevHostdev(const virDomainDef *def)
  }
  
  
+bool

+virDomainDefHasVDPANet(const virDomainDef *def)
+{
+size_t i;
+
+for (i = 0; i < def->nnets; i++) {
+if (virDomainNetGetActualType(def->nets[i]) == 
VIR_DOMAIN_NET_TYPE_VDPA)
+return true;
+}
+
+return false;
+}
+
+
  bool
  virDomainDefHasOldStyleUEFI(const virDomainDef *def)
  {
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index da32016b01..aa15184821 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -4061,6 +4061,9 @@ virDomainDefHasVFIOHostdev(const virDomainDef *def);
  bool
  virDomainDefHasMdevHostdev(const virDomainDef *def);
  
+bool

+virDomainDefHasVDPANet(const virDomainDef *def);
+
  bool
  virDomainDefHasOldStyleUEFI(const virDomainDef *def);
  
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms

index 526dcee11a..1bf8165520 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -332,6 +332,7 @@ virDomainDefHasOldStyleROUEFI;
  virDomainDefHasOldStyleUEFI;
  virDomainDefHasUSB;
  virDomainDefHasVcpusOffline;
+virDomainDefHasVDPANet;
  virDomainDefHasVFIOHostdev;
  virDomainDefLifecycleActionAllowed;
  virDomainDefMaybeAddController;





Re: [PATCH 1/1] domain_cgroup.c: update domain after setting blkio.weight

2021-03-23 Thread Daniel Henrique Barboza




On 3/23/21 7:03 AM, Ján Tomko wrote:

On a Monday in 2021, Daniel Henrique Barboza wrote:

Commit ac87d3520ad5 consolidated common cgroup code between the QEMU and
lxc drivers in domain_cgroup.c. In this process, in
virDomainCgroupSetupDomainBlkioParameters(), a call to
virCgroupGetBlkioWeight() went missing.

The result is that 'virsh blkiotune' is setting the blkio.weight for the
guest in the host cgroup, but not on the domain XML, because
virCgroupGetBlkioWeight() is also used to write the blkio.weight value
in the domain object.

Fix it by adding the virCgroupGetBlkioWeight() call in the
virDomainCgroupSetupDomainBlkioParameters() helper.

Fixes: 5493217b940ee9ea72b581270adb3ab9ba245148


fatal: bad object 5493217b940ee9ea72b581270adb3ab9ba245148


I have no idea where this commit is from. The strangest thing is that
I referenced the right commit up there \_o_/

I'll change it to ac87d3520ad542d558854a72b0ae0a81fddc6747 before
pushing.





Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1941407
Signed-off-by: Daniel Henrique Barboza 
---
src/hypervisor/domain_cgroup.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)



Reviewed-by: Ján Tomko 



Thanks!


DHB



Jano




[PATCH 1/1] domain_cgroup.c: update domain after setting blkio.weight

2021-03-22 Thread Daniel Henrique Barboza
Commit ac87d3520ad5 consolidated common cgroup code between the QEMU and
lxc drivers in domain_cgroup.c. In this process, in
virDomainCgroupSetupDomainBlkioParameters(), a call to
virCgroupGetBlkioWeight() went missing.

The result is that 'virsh blkiotune' is setting the blkio.weight for the
guest in the host cgroup, but not on the domain XML, because
virCgroupGetBlkioWeight() is also used to write the blkio.weight value
in the domain object.

Fix it by adding the virCgroupGetBlkioWeight() call in the
virDomainCgroupSetupDomainBlkioParameters() helper.

Fixes: 5493217b940ee9ea72b581270adb3ab9ba245148
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1941407
Signed-off-by: Daniel Henrique Barboza 
---
 src/hypervisor/domain_cgroup.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/hypervisor/domain_cgroup.c b/src/hypervisor/domain_cgroup.c
index eb4fa20a9e..05e3aa7e6a 100644
--- a/src/hypervisor/domain_cgroup.c
+++ b/src/hypervisor/domain_cgroup.c
@@ -104,7 +104,8 @@ virDomainCgroupSetupDomainBlkioParameters(virCgroupPtr 
cgroup,
 virTypedParameterPtr param = ¶ms[i];
 
 if (STREQ(param->field, VIR_DOMAIN_BLKIO_WEIGHT)) {
-if (virCgroupSetBlkioWeight(cgroup, params[i].value.ui) < 0)
+if (virCgroupSetBlkioWeight(cgroup, params[i].value.ui) < 0 ||
+virCgroupGetBlkioWeight(cgroup, &def->blkio.weight) < 0)
 ret = -1;
 } else if (STREQ(param->field, VIR_DOMAIN_BLKIO_DEVICE_WEIGHT) ||
STREQ(param->field, VIR_DOMAIN_BLKIO_DEVICE_READ_IOPS) ||
-- 
2.30.2



Re: [PATCH v1] tests: Adjust libxlxml2domconfigtest to work with Xen < 4.8

2021-03-16 Thread Daniel Henrique Barboza




On 3/8/21 10:29 AM, Olaf Hering wrote:

Commit fcdc387410fadfb066b95395c5b5d2a6a16f7066 used a libxl API which
is only available since Xen 4.8.

Due to lack of a specific guard for this API change, reuse another
guard from libxl.h.

Signed-off-by: Olaf Hering 
---


The patch failed the sc_preprocessor_indentation test:

--- stderr ---
cppi: /home/danielhb/kvm-project/libvirt/tests/libxlxml2domconfigtest.c: line 
108: not properly indented
cppi: /home/danielhb/kvm-project/libvirt/tests/libxlxml2domconfigtest.c: line 
114: not properly indented
build-aux/syntax-check.mk: incorrect preprocessor indentation
make: *** [/home/danielhb/kvm-project/libvirt/build-aux/syntax-check.mk:762: 
sc_preprocessor_indentation] Error 1



This change fixes it:

$ git diff
diff --git a/tests/libxlxml2domconfigtest.c b/tests/libxlxml2domconfigtest.c
index c13a562a3c..3c133ac6f0 100644
--- a/tests/libxlxml2domconfigtest.c
+++ b/tests/libxlxml2domconfigtest.c
@@ -105,13 +105,13 @@ testCompareXMLToDomConfig(const char *xmlfile,
  */
 # ifndef LIBXL_HAVE_BUILDINFO_APIC
 if (expectconfig.c_info.type == LIBXL_DOMAIN_TYPE_HVM) {
-# ifdef LIBXL_HAVE_MEMKB_64BITS
+#  ifdef LIBXL_HAVE_MEMKB_64BITS
 /*
  * This part of the libxl API was changed without a guard in Xen 4.8.
  * Reuse another Xen 4.8 specific conditional.
  */
 libxl_defbool_unset(&expectconfig.b_info.acpi);
-# endif
+#  endif
 libxl_defbool_set(&expectconfig.b_info.u.hvm.apic, true);
 libxl_defbool_set(&expectconfig.b_info.u.hvm.acpi, true);
 }
$


If the maintainer is willing to amend it before pushing it:


Reviewed-by: Daniel Henrique Barboza 



  tests/libxlxml2domconfigtest.c | 6 ++
  1 file changed, 6 insertions(+)

diff --git a/tests/libxlxml2domconfigtest.c b/tests/libxlxml2domconfigtest.c
index d58be1211b..c13a562a3c 100644
--- a/tests/libxlxml2domconfigtest.c
+++ b/tests/libxlxml2domconfigtest.c
@@ -105,7 +105,13 @@ testCompareXMLToDomConfig(const char *xmlfile,
   */
  # ifndef LIBXL_HAVE_BUILDINFO_APIC
  if (expectconfig.c_info.type == LIBXL_DOMAIN_TYPE_HVM) {
+# ifdef LIBXL_HAVE_MEMKB_64BITS
+/*
+ * This part of the libxl API was changed without a guard in Xen 4.8.
+ * Reuse another Xen 4.8 specific conditional.
+ */
  libxl_defbool_unset(&expectconfig.b_info.acpi);
+# endif
  libxl_defbool_set(&expectconfig.b_info.u.hvm.apic, true);
  libxl_defbool_set(&expectconfig.b_info.u.hvm.acpi, true);
  }





Re: [PATCH] vm : forbid to start a removing vm

2021-03-16 Thread Daniel Henrique Barboza




On 3/10/21 10:13 PM, Hogan Wang wrote:

From: Zhuang Shengen 

When a vm is doing migration phase confirm, and then start it concurrently,
it will lead to the vm out of libvirtd control.

Cause Analysis:
1. thread1 migrate vm out.
2. thread2 start the migrating vm.
3. thread1 remove vm from domain list after migrate success.
4. thread2 acquired the vm job success and start the vm.
5. cannot find the vm any more by 'virsh list' command. Actually,
the started vm is not exist in the domain list.

Solution:
Check the vm->removing state before start.


Signed-off-by: Zhuang Shengen 
Reviewed-by: Hogan Wang 
---


Reviewed-by: Daniel Henrique Barboza 



  src/qemu/qemu_driver.c | 6 ++
  1 file changed, 6 insertions(+)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index d1a3659774..a5dfea94cb 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -6637,6 +6637,12 @@ qemuDomainCreateWithFlags(virDomainPtr dom, unsigned int 
flags)
  goto endjob;
  }
  
+if (vm->removing) {

+virReportError(VIR_ERR_OPERATION_INVALID,
+   "%s", _("domain is already removing"));
+goto endjob;
+}
+
  if (qemuDomainObjStart(dom->conn, driver, vm, flags,
 QEMU_ASYNC_JOB_START) < 0)
  goto endjob;





Re: [PATCH v4 1/1] qemu: add per-vcpu delay stats

2021-03-04 Thread Daniel Henrique Barboza




On 2/19/21 5:08 PM, Aleksei Zakharov wrote:

This patch adds delay time (steal time inside guest) to libvirt
domain per-vcpu stats. Delay time is an important performance metric.
It is a consequence of the overloaded CPU. Knowledge of the delay
time of a virtual machine helps to understand if it is affected and
estimate the impact.

As a result, it is possible to react exactly when needed and
rebalance the load between hosts. This is used by cloud providers
to provide quality of service, especially when the CPU is
oversubscribed.

It's more convenient to work with this metric in a context of a
libvirt domain. Any monitoring software may use this information.

Signed-off-by: Aleksei Zakharov 
---
  docs/manpages/virsh.rst |  4 
  src/libvirt-domain.c|  4 
  src/qemu/qemu_driver.c  | 44 +++--
  3 files changed, 50 insertions(+), 2 deletions(-)

diff --git a/docs/manpages/virsh.rst b/docs/manpages/virsh.rst
index e3afa48f7b..a2b83ddfaa 100644
--- a/docs/manpages/virsh.rst
+++ b/docs/manpages/virsh.rst
@@ -2295,6 +2295,10 @@ When selecting the *--state* group the following fields 
are returned:
  * ``vcpu..halted`` - virtual CPU  is halted: yes or
no (may indicate the processor is idle or even disabled,
depending on the architecture)
+* ``vcpu..delay`` - time the vCPU  thread was enqueued by the
+  host scheduler, but was waiting in the queue instead of running.
+  Exposed to the VM as a steal time.
+
  
  
  *--interface* returns:

diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c
index 4af0166872..e54d11e513 100644
--- a/src/libvirt-domain.c
+++ b/src/libvirt-domain.c
@@ -11693,6 +11693,10 @@ virConnectGetDomainCapabilities(virConnectPtr conn,
   * "vcpu..halted" - virtual CPU  is halted, may indicate the
   *   processor is idle or even disabled, depending
   *   on the architecture)
+ * "vcpu..delay" - time the vCPU  thread was enqueued by the
+ *  host scheduler, but was waiting in the queue
+ *  instead of running. Exposed to the VM as a steal
+ *  time.
   *
   * VIR_DOMAIN_STATS_INTERFACE:
   * Return network interface statistics (from domain point of view).
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index b9bbdf8d48..9ec3c8fce7 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -1332,6 +1332,34 @@ static char *qemuConnectGetCapabilities(virConnectPtr 
conn) {
  return virCapabilitiesFormatXML(caps);
  }
  
+static int

+qemuGetSchedstatDelay(unsigned long long *cpudelay,
+ pid_t pid, pid_t tid)
+{
+g_autofree char *proc = NULL;
+unsigned long long oncpu = 0;
+g_autofree FILE *schedstat = NULL;


So, the most common practice in the project is to declare the file fds with
VIR_AUTOCLOSE to avoid having to close the fd at the end. There are a lot of
examples in src/util/virnetdev.c.  This is the first time I see
'g_autofree FILE *'.



+
+if (tid)
+proc = g_strdup_printf("/proc/%d/task/%d/schedstat", (int)pid, 
(int)tid);
+else
+proc = g_strdup_printf("/proc/%d/schedstat", (int)pid);
+
+schedstat = fopen(proc, "r");
+if (!schedstat) {
+virReportError(VIR_ERR_INTERNAL_ERROR,
+   _("Unable to open schedstat file at '%s'"),
+   proc);
+}
+if (fscanf(schedstat, "%llu %llu", &oncpu, cpudelay) < 2) {
+virReportError(VIR_ERR_INTERNAL_ERROR,
+   _("Unable to parse schedstat info at '%s'"),
+   proc);
+}
+
+VIR_FORCE_FCLOSE(schedstat);



That said, reading the change log for the patch I see that someone already
mentioned the needed to close the FD in v1 and you fixed it in v2, so I'll
take that this code, albeit unusual to me, works. If it doesn't, it's a
rather trivial amend that the maintainer can do before pushing.


Reviewed-by: Daniel Henrique Barboza 





+return 0;
+}
  
  static int

  qemuGetSchedInfo(unsigned long long *cpuWait,
@@ -1470,6 +1498,7 @@ static int
  qemuDomainHelperGetVcpus(virDomainObjPtr vm,
   virVcpuInfoPtr info,
   unsigned long long *cpuwait,
+ unsigned long long *cpudelay,
   int maxinfo,
   unsigned char *cpumaps,
   int maplen)
@@ -1529,6 +1558,11 @@ qemuDomainHelperGetVcpus(virDomainObjPtr vm,
  return -1;
  }
  
+if (cpudelay) {

+if (qemuGetSchedstatDelay(&(cpudelay[ncpuinfo]), vm->pid, vcpupid) 
< 0)
+return -1;
+}
+
  ncpuinfo++;
  }
  
@@ -4873,7 +4907,7 @@ qemuDomainGetVcpus(virDomainPtr dom,

  

Re: [libvirt PATCH v2 1/1] qemuProcessUpdateGuestCPU: Check host cpu for forbidden features

2021-03-04 Thread Daniel Henrique Barboza




On 2/25/21 10:23 AM, Tim Wiederhake wrote:

See https://bugzilla.redhat.com/show_bug.cgi?id=1840770

Signed-off-by: Tim Wiederhake 
---


Reviewed-by: Daniel Henrique Barboza 


  src/qemu/qemu_process.c | 27 +++
  1 file changed, 27 insertions(+)

diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index bfa742577f..cecf606312 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -6149,6 +6149,33 @@ qemuProcessUpdateGuestCPU(virDomainDefPtr def,
  if (virCPUConvertLegacy(hostarch, def->cpu) < 0)
  return -1;
  
+if (def->cpu->check != VIR_CPU_CHECK_NONE) {

+virCPUDefPtr host;
+size_t i;
+
+host = virQEMUCapsGetHostModel(qemuCaps, def->virtType,
+   VIR_QEMU_CAPS_HOST_CPU_FULL);
+
+for (i = 0; i < def->cpu->nfeatures; ++i) {
+virCPUFeatureDefPtr feature;
+
+if (def->cpu->features[i].policy != VIR_CPU_FEATURE_FORBID)
+continue;
+
+feature = virCPUDefFindFeature(host, def->cpu->features[i].name);
+if (!feature)
+continue;
+
+if (feature->policy == VIR_CPU_FEATURE_DISABLE)
+continue;
+
+virReportError(VIR_ERR_CPU_INCOMPATIBLE,
+   _("Host CPU provides forbidden feature '%s'"),
+   def->cpu->features[i].name);
+return -1;
+}
+}
+
  /* nothing to update for host-passthrough / maximum */
  if (def->cpu->mode != VIR_CPU_MODE_HOST_PASSTHROUGH &&
  def->cpu->mode != VIR_CPU_MODE_MAXIMUM) {





Re: [PATCH] meson: Add documentation installation directory option

2021-03-04 Thread Daniel Henrique Barboza




On 2/26/21 4:11 PM, Chris Mayo wrote:

Allow the directory to be chosen at installation time, to support local
conventions e.g. versioning.

Signed-off-by: Chris Mayo 
---


Reviewed-by: Daniel Henrique Barboza 


  meson.build   | 6 +-
  meson_options.txt | 1 +
  2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/meson.build b/meson.build
index 369548f127..5c7a335947 100644
--- a/meson.build
+++ b/meson.build
@@ -83,8 +83,12 @@ mandir = prefix / get_option('mandir')
  sbindir = prefix / get_option('sbindir')
  sharedstatedir = prefix / get_option('sharedstatedir')
  
+docdir = get_option('docdir')

+if docdir == ''
+  docdir = datadir / 'doc' / meson.project_name()
+endif
+
  confdir = sysconfdir / meson.project_name()
-docdir = datadir / 'doc' / meson.project_name()
  pkgdatadir = datadir / meson.project_name()
  
  
diff --git a/meson_options.txt b/meson_options.txt

index e5d79c2b6b..2606648b64 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -7,6 +7,7 @@ option('expensive_tests', type: 'feature', value: 'auto', 
description: 'set the
  option('test_coverage', type: 'boolean', value: false, description: 'turn on 
code coverage instrumentation')
  option('git_werror', type: 'feature', value: 'auto', description: 'use 
-Werror if building from GIT')
  option('rpath', type: 'feature', value: 'auto', description: 'whether to 
include rpath information in installed binaries and libraries')
+option('docdir', type: 'string', value: '', description: 'documentation 
installation directory')
  option('docs', type: 'feature', value: 'auto', description: 'whether to 
generate documentation')
  option('tests', type: 'feature', value: 'auto', description: 'whether to 
build tests')
  





Re: using libvirt 4.5 with upstream qemu

2021-03-02 Thread Daniel Henrique Barboza




On 3/2/21 7:40 AM, Thanos Makatos wrote:




-Original Message-
From: Daniel Henrique Barboza 
Sent: 01 March 2021 18:07
To: Peter Krempa ; Thanos Makatos

Cc: libvir-list@redhat.com
Subject: Re: using libvirt 4.5 with upstream qemu



On 3/1/21 12:47 PM, Peter Krempa wrote:

On Mon, Mar 01, 2021 at 15:30:58 +, Thanos Makatos wrote:

I'm trying to use QEMU master with libvirt 4.5 and QEMU seems to be
hanging when I try to start a guest.

My environment is a modified CentOS 7.9 installation using libvirt
4.5.0. When I use a modified version of QEMU 2.12 (reasonably close
to the stock CentOS
version) everything works fine. When I try to use a fairly recent
version of QEMU (e.g. v5.2.0-729-g89ff714f4b).

qemu 118657  1.6  0.0  0 0 ?Z14:50   0:00 [qemu-kvm]



qemu 118664  0.0  0.0 207340  3560 ?Ssl  14:50   0:00

/usr/libexec/qemu-kvm -S -no-user-config -nodefaults -nographic -machine
none,accel=kvm:tcg -qmp
unix:/var/lib/libvirt/qemu/capabilities.monitor.sock,server,nowait -pidfile
/var/lib/libvirt/qemu/capabilities.pidfile -daemonize

qemu 118666  0.0  0.0 275008 13916 ?Sl   14:50   0:00

/usr/libexec/qemu-kvm -S -no-user-config -nodefaults -nographic -machine
none,accel=kvm:tcg -qmp
unix:/var/lib/libvirt/qemu/capabilities.monitor.sock,server,nowait -pidfile
/var/lib/libvirt/qemu/capabilities.pidfile -daemonize


These are possibly a leftover from libvirt's capability probing. I
recall that we had some issue with capability detection qemu instances
getting stuck but I don't remember the details any more.


Not sure if related to this reported problem, but upstream QEMU when
compiled with the trace backend was having problems daemonizing. I
experienced a similar issue in the start of the year when running upstream
Libvirt with upstream QEMU.

I posted a patch fixing it in QEMU [1] but it wasn't pushed as of today.
I am not sure if the problem was fixed in another way or if the patch I posted
ended up left behind.

Thanos, if you're compiling QEMU with a trace backend (e.g. with --enable-
trace-backend= in ../configure) it might be worth compiling it without this
option. There is a chance you're hitting same problem I mentioned above.


Thanks Daniel, removing --enable-trace-backend did fix the issue!



Glad I could help. Thanks for checking it out.

Guess I'll ping the QEMU mailing list about the fix I posted. Seems like the
daemonization is still broken upstream with the trace backend enabled.



DHB















Re: using libvirt 4.5 with upstream qemu

2021-03-01 Thread Daniel Henrique Barboza




On 3/1/21 12:47 PM, Peter Krempa wrote:

On Mon, Mar 01, 2021 at 15:30:58 +, Thanos Makatos wrote:

I'm trying to use QEMU master with libvirt 4.5 and QEMU seems to be hanging
when I try to start a guest.

My environment is a modified CentOS 7.9 installation using libvirt 4.5.0. When
I use a modified version of QEMU 2.12 (reasonably close to the stock CentOS
version) everything works fine. When I try to use a fairly recent version of
QEMU (e.g. v5.2.0-729-g89ff714f4b).

   qemu 118657  1.6  0.0  0 0 ?Z14:50   0:00 [qemu-kvm] 

   qemu 118664  0.0  0.0 207340  3560 ?Ssl  14:50   0:00 
/usr/libexec/qemu-kvm -S -no-user-config -nodefaults -nographic -machine 
none,accel=kvm:tcg -qmp 
unix:/var/lib/libvirt/qemu/capabilities.monitor.sock,server,nowait -pidfile 
/var/lib/libvirt/qemu/capabilities.pidfile -daemonize
   qemu 118666  0.0  0.0 275008 13916 ?Sl   14:50   0:00 
/usr/libexec/qemu-kvm -S -no-user-config -nodefaults -nographic -machine 
none,accel=kvm:tcg -qmp 
unix:/var/lib/libvirt/qemu/capabilities.monitor.sock,server,nowait -pidfile 
/var/lib/libvirt/qemu/capabilities.pidfile -daemonize


These are possibly a leftover from libvirt's capability probing. I
recall that we had some issue with capability detection qemu instances
getting stuck but I don't remember the details any more.


Not sure if related to this reported problem, but upstream QEMU when
compiled with the trace backend was having problems daemonizing. I
experienced a similar issue in the start of the year when running
upstream Libvirt with upstream QEMU.

I posted a patch fixing it in QEMU [1] but it wasn't pushed as of today.
I am not sure if the problem was fixed in another way or if the patch I
posted ended up left behind.

Thanos, if you're compiling QEMU with a trace backend (e.g. with
--enable-trace-backend= in ../configure) it might be worth compiling it
without this option. There is a chance you're hitting same problem I
mentioned above.



[1] https://lists.gnu.org/archive/html/qemu-devel/2021-01/msg00541.html



Thanks,


DHB





/var/lib/libvirt/qemu/capabilities.pidfile contains the PID of the 2nd QEMU
process and by experimenting I found that by killing the QEMU process NOT in
the PID file the same thing happens again (maybe once more or twice) and then
the guest boots fine.

Does libvirt have some specific QEMU dependency? Is there some compatibility
matrix I might have missed? I understand this may not be a supported
configuration given that I'm not using vanilla libvirt/QEMU, however I'd
appreciate some pointers so I can further debug this. I've trying debugging
this in case there's some obvious error but didn't find anything interesting.

Any ideas?


In general, libvirt can't guarantee support of future qemu versions as
qemu evolving and recently also deprecating and removing superseded
configuration approaches, so you must cross-check with qemu's support
policy.

For debugging, debug logs may be helpful. In case a real VM getting
stuck also the VM log file, but in your case the capability processes
don't have that.





Re: [PATCH RESEND 20/20] virhostdev.c: remove missing PCI devs from hostdev manager

2021-02-22 Thread Daniel Henrique Barboza




On 2/22/21 1:12 AM, Laine Stump wrote:

On 1/18/21 2:53 PM, Daniel Henrique Barboza wrote:

virHostdevReAttachPCIDevices() is called when we want to re-attach
a list of hostdevs back to the host, either on the shutdown path or
via a 'virsh detach-device' call.  This function always count on the
existence of the device in the host to work, but this can lead to
problems. For example, a SR-IOV device can be removed via an admin
"echo 0 > /sys/bus/pci/devices//sriov_numvfs", making the kernel
fire up and eventfd_signal() to the process, asking for the process to
release the device. The result might vary depending on the device driver
and OS/arch, but two possible outcomes are:

1) the hypervisor driver will detach the device from the VM, issuing a
delete event to Libvirt. This can be observed in QEMU;

2) the 'echo 0 > ...' will hang waiting for the device to be unplugged.
This means that the VM process failed/refused to release the hostdev back
to the host, and the hostdev will be detached during VM shutdown.

Today we don't behave well for both cases. We'll fail to remove the PCI device
reference from mgr->activePCIHostdevs and mgr->inactivePCIHostdevs because
we rely on the existence of the PCI device conf file in the sysfs. Attempting
to re-utilize the same device (assuming it is now present back in the host)
can result in an error like this:

$ ./run tools/virsh start vm1-sriov --console
error: Failed to start domain vm1-sriov
error: Requested operation is not valid: PCI device :01:00.2 is in use by 
driver QEMU, domain vm1-sriov

For (1), a VM destroy/start cycle is needed to re-use the VF in the guest.
For (2), the effect is more nefarious, requiring a Libvirtd daemon restart
to use the VF again in any guest.

We can make it a bit better by checking, during virHostdevReAttachPCIDevices(),
if there is any missing PCI device that will be left behind in activePCIHostdevs
and inactivePCIHostdevs lists. Remove any missing device found from both lists,
unconditionally, matching the current state of the host. This change affects
the code path in (1) (processDeviceDeletedEvent into qemuDomainRemoveDevice, all
the way back to qemuHostdevReAttachPCIDevices) and also in (b) (qemuProcessStop
into qemuHostdevReAttachDomainDevices).

NB: Although this patch enables the possibility of 'outside Libvirt' SR-IOV
hotunplug of PCI devices, if the hypervisor and the PCI driver copes with it,
our goal is to mitigate what it is still considered an user oopsie. For all''


This is one of those odd cases where you use "a" before a word starting with a vowel rather than 
"an". It's that way because the *sound* starting the next word is "you" rather than "ooh".


Oh yeah thanks for pointing this out. I learned this 20+ years ago and
forgot it along the road. Heavy metal lyrics and World of Warcraft public
chat aren't the best sources for learning proper English grammar, so it
seems.





supported purposes, the admin must remove the SR-IOV VFs from all running 
domains
before removing the VFs from the host.

Resolves:  https://gitlab.com/libvirt/libvirt/-/issues/72
Signed-off-by: Daniel Henrique Barboza 
---
  src/hypervisor/virhostdev.c | 38 +
  1 file changed, 38 insertions(+)

diff --git a/src/hypervisor/virhostdev.c b/src/hypervisor/virhostdev.c
index c708791eec..ed43733e71 100644
--- a/src/hypervisor/virhostdev.c
+++ b/src/hypervisor/virhostdev.c
@@ -1077,6 +1077,40 @@ virHostdevReAttachPCIDevicesImpl(virHostdevManagerPtr 
mgr,
  }
+static void
+virHostdevDeleteMissingPCIDevices(virHostdevManagerPtr mgr,
+  virDomainHostdevDefPtr *hostdevs,
+  int nhostdevs)
+{
+    size_t i;
+
+    if (nhostdevs == 0)
+    return;
+
+    virObjectLock(mgr->activePCIHostdevs);
+    virObjectLock(mgr->inactivePCIHostdevs);
+
+    for (i = 0; i < nhostdevs; i++) {
+    virDomainHostdevDef *hostdev = hostdevs[i];
+    virDomainHostdevSubsysPCI *pcisrc = &hostdev->source.subsys.u.pci;
+    g_autoptr(virPCIDevice) pci = NULL;
+
+    if (virHostdevGetPCIHostDevice(hostdev, &pci) != -2)
+    continue;
+
+    /* The PCI device from 'hostdev' does not exist in the host
+ * anymore. Delete it from both active and inactive lists to
+ * reflect the current host state.
+ */
+    virPCIDeviceListDel(mgr->activePCIHostdevs, &pcisrc->addr);
+    virPCIDeviceListDel(mgr->inactivePCIHostdevs, &pcisrc->addr);
+    }
+
+    virObjectUnlock(mgr->activePCIHostdevs);
+    virObjectUnlock(mgr->inactivePCIHostdevs);


It makes me nervous that you're unlocking these lists in the same order that 
you lock them, since that could theoretically lead to a deadlock. I haven't 
even thought beyond this single func

Re: [PATCH] qemu_driver.c: Coverity fix in qemuNodeDeviceDetachFlags()

2021-02-18 Thread Daniel Henrique Barboza




On 2/18/21 9:52 AM, John Ferlan wrote:



On 2/18/21 7:33 AM, Daniel Henrique Barboza wrote:

Commit 76f47889326c4 made qemuNodeDeviceDetachFlags() unusable due to an
'if then else if' chain that will always results in a 'return -1',
regardless of 'driverName' input. This slipped through review process
and Gitlab CI, making it clear now that there is no unit tests
exercising this code ATM.

LUckily John Ferlan caught this up with his Coverity scan and spared us
from an unneeded headache later on.

Fixes: 76f47889326c45d2732711bc6dd5751aaf6e5194
Reported-by: John Ferlan 
Signed-off-by: Daniel Henrique Barboza 
---
  src/qemu/qemu_driver.c | 26 +++---
  1 file changed, 15 insertions(+), 11 deletions(-)



I can vouch this does make Coverity happy again.  I do agree w/ Jano no
need to be too elaborate on slipping thru cracks And when I do
create patches (rarely) now for Coverity, I'll just attribute it to
"Found by Coverity" and be done with it. You already put the Reported-by
so that's probably sufficient!


It was my attempt to save face by claiming that I failed because there were no
unit tests :)

But you gotta a good point though. I'll remove this except before pushing it.


Thanks,


DHB




Reviewed-by: John Ferlan 

John





[PATCH] qemu_driver.c: Coverity fix in qemuNodeDeviceDetachFlags()

2021-02-18 Thread Daniel Henrique Barboza
Commit 76f47889326c4 made qemuNodeDeviceDetachFlags() unusable due to an
'if then else if' chain that will always results in a 'return -1',
regardless of 'driverName' input. This slipped through review process
and Gitlab CI, making it clear now that there is no unit tests
exercising this code ATM.

LUckily John Ferlan caught this up with his Coverity scan and spared us
from an unneeded headache later on.

Fixes: 76f47889326c45d2732711bc6dd5751aaf6e5194
Reported-by: John Ferlan 
Signed-off-by: Daniel Henrique Barboza 
---
 src/qemu/qemu_driver.c | 26 +++---
 1 file changed, 15 insertions(+), 11 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index f1035a536e..b9bbdf8d48 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -11998,7 +11998,6 @@ qemuNodeDeviceDetachFlags(virNodeDevicePtr dev,
   unsigned int flags)
 {
 virQEMUDriverPtr driver = dev->conn->privateData;
-bool vfio = qemuHostdevHostSupportsPassthroughVFIO();
 virHostdevManagerPtr hostdev_mgr = driver->hostdevMgr;
 
 virCheckFlags(0, -1);
@@ -12006,22 +12005,27 @@ qemuNodeDeviceDetachFlags(virNodeDevicePtr dev,
 if (!driverName)
 driverName = "vfio";
 
-if (STREQ(driverName, "vfio") && !vfio) {
-virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
-   _("VFIO device assignment is currently not "
- "supported on this system"));
- return -1;
-} else if (STREQ(driverName, "kvm")) {
+/* Only the 'vfio' driver is supported and a special error message for
+ * the previously supported 'kvm' driver is provided below. */
+if (STRNEQ(driverName, "vfio") && STRNEQ(driverName, "kvm")) {
+virReportError(VIR_ERR_INVALID_ARG,
+   _("unknown driver name '%s'"), driverName);
+return -1;
+}
+
+if (STREQ(driverName, "kvm")) {
 virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
_("KVM device assignment is no longer "
  "supported on this system"));
 return -1;
-} else {
-virReportError(VIR_ERR_INVALID_ARG,
-   _("unknown driver name '%s'"), driverName);
-return -1;
 }
 
+if (!qemuHostdevHostSupportsPassthroughVFIO()) {
+virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
+   _("VFIO device assignment is currently not "
+ "supported on this system"));
+ return -1;
+}
 
 /* virNodeDeviceDetachFlagsEnsureACL() is being called by
  * virDomainDriverNodeDeviceDetachFlags() */
-- 
2.29.2



Re: [PATCH v2 07/10] qemu_driver.c: validate 'driverName' earlier in qemuNodeDeviceDetachFlags()

2021-02-18 Thread Daniel Henrique Barboza




On 2/18/21 8:30 AM, John Ferlan wrote:



On 2/2/21 8:06 PM, Daniel Henrique Barboza wrote:

The validation of 'driverName' does not depend on any other state and can be
done right on the start of the function. We can fail earlier while avoiding
a cleanup jump.

Reviewed-by: Ján Tomko 
Signed-off-by: Daniel Henrique Barboza 
---
  src/qemu/qemu_driver.c | 41 -
  1 file changed, 20 insertions(+), 21 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c

index 64ae8fafc0..c6ba33e4ad 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -11982,6 +11982,25 @@ qemuNodeDeviceDetachFlags(virNodeDevicePtr dev,
  
  virCheckFlags(0, -1);
  
+if (!driverName)

+driverName = "vfio";
+
+if (STREQ(driverName, "vfio") && !vfio) {
+virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
+   _("VFIO device assignment is currently not "
+ "supported on this system"));
+ return -1;
+} else if (STREQ(driverName, "kvm")) {
+virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
+   _("KVM device assignment is no longer "
+ "supported on this system"));
+return -1;
+} else {
+virReportError(VIR_ERR_INVALID_ARG,
+   _("unknown driver name '%s'"), driverName);
+return -1;
+}
+


Coverity points out the rest of this is unreachable now (even with the
subsequent patch).



ooo. I'll fix it. Thanks for the heads up John!




  if (!(nodeconn = virGetConnectNodeDev()))
  goto cleanup;
  
@@ -12013,27 +12032,7 @@ qemuNodeDeviceDetachFlags(virNodeDevicePtr dev,

  if (!pci)
  goto cleanup;
  
-if (!driverName)

-driverName = "vfio";
-
-if (STREQ(driverName, "vfio")) {
-if (!vfio) {
-virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
-   _("VFIO device assignment is currently not "
- "supported on this system"));
-goto cleanup;
-}
-virPCIDeviceSetStubDriver(pci, VIR_PCI_STUB_DRIVER_VFIO);


This section seems to be more than just code motion...  it used to pass
thru here when vfio = true, but with the movement it would fall into the
catch all else.

John


-} else if (STREQ(driverName, "kvm")) {
-virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
-   _("KVM device assignment is no longer "
- "supported on this system"));
-goto cleanup;
-} else {
-virReportError(VIR_ERR_INVALID_ARG,
-   _("unknown driver name '%s'"), driverName);
-goto cleanup;
-}
+virPCIDeviceSetStubDriver(pci, VIR_PCI_STUB_DRIVER_VFIO);
  
  ret = virHostdevPCINodeDeviceDetach(hostdev_mgr, pci);

   cleanup:







Re: [PATCH v2 10/10] scripts/check-aclrules.py: check ACL for domain_driver.c ACL callers

2021-02-17 Thread Daniel Henrique Barboza




On 2/17/21 1:41 PM, Ján Tomko wrote:

On a Tuesday in 2021, Daniel Henrique Barboza wrote:

This script works under two specific conditions. For each opened file,
search for all functions that has ACL calls and store them, and see
if there is a vir*DriverPtr struct declared in it. For each implementation
found, check if there is an ACL verification inside it, and error out if
none was found. The script also supports the concept of stub, where another
function takes the responsibility for the ACL call instead of the
original API.

Unfortunately this is not enough to cover the new scenario we have now,
with domain_driver.c containing helper functions that execute the ACL
calls. The script does not store state between files because, until now,
it wasn't needed to - APIs and stubs and vir*DriverPtr declarations were
always in the same file. Also, the script will not check for ACL in functions
that does not belong to a vir*DriverPtr interface. What we have now in
domain_driver.c breaks both assumptions: the functions are in a different
file, and there is no vir*DriverPtr being implemented in the file that
uses these functions.

This patch changes check-aclrules.py to accomodate this scenario. The helpers
that have ACL checks are stored beforehand in aclFuncHelpers, allowing other
files to use them to recognize a stub situation. In case the current file
being analyzed is domain_driver.c itself, we'll do a manual check using
aclFuncHelpers to verify that these functions indeed have ACL checks.

Signed-off-by: Daniel Henrique Barboza 
---
scripts/check-aclrules.py  | 25 -
src/hypervisor/meson.build |  2 ++
2 files changed, 26 insertions(+), 1 deletion(-)



Reviewed-by: Ján Tomko 

Also, consider suppressing cc's in your .gitconfig:

[sendemail]
     suppresscc = all
     signedoffbycc = no

(Sadly I don't remember whether the last line is actually needed)


Usually I delete the copies of patches I get via cc: and only deal with
the copies sent to the mailing list, but it looks like here you CC'd me
only on the patches I've already reviewed, which does not seem useful :)


Ooops, sorry about that. I forgot that git sendmail also adds CCs via 
reviewed-by
tags (not sure why). I'll use supresscc=all to be safe.


Thanks for the review!



DHB




Jano




Re: [PATCH RESEND 00/20] handle missing SR-IOV VF hostdevs during running domains

2021-02-16 Thread Daniel Henrique Barboza

Ping for reviews (patches 1-4 and 7-8 already pushed).



On 1/18/21 4:53 PM, Daniel Henrique Barboza wrote:

This is the rebased version of

https://www.redhat.com/archives/libvir-list/2021-January/msg00028.html

with master at 57b1ddcaaa5b5. No changes made aside from trivial conflicts
fixes.

I also removed the military jargon from the previous subject to make it
clear what this series is doing.

Daniel Henrique Barboza (20):
   virpci, domain_audit: use virPCIDeviceAddressAsString()
   qemu, lxc: move NodeDeviceGetPCIInfo() function to domain_driver.c
   domain_driver.c: use PCI address with
 virDomainDriverNodeDeviceGetPCIInfo()
   virpci.c: simplify virPCIDeviceNew() signature
   virpci: introduce virPCIDeviceExists()
   virhostdev.c: virHostdevGetPCIHostDevice() now reports missing device
   security_selinux.c: modernize set/restore hostdev subsys label
 functions
   security_dac.c: modernize hostdev label set/restore functions
   dac, selinux: skip setting/restoring label for absent PCI devices
   libvirt-nodedev.c: remove return value from virNodeDeviceFree()
   qemu_driver.c: modernize qemuNodeDeviceReAttach()
   libxl_driver.c: modernize libxlNodeDeviceReAttach()
   virsh-domain.c: modernize cmdDetachDevice()
   virhostdev.c: add virHostdevIsPCIDevice() helper
   qemu_cgroup.c: skip absent PCI devices in qemuTeardownHostdevCgroup()
   virpci.c: use virPCIDeviceAddressPtr in virPCIDeviceListFindIndex()
   virpci.c: use virPCIDeviceAddressPtr in virPCIDeviceListFind()
   virpci.c: use virPCIDeviceAddressPtr in virPCIDeviceListSteal()
   virpci.c: use virPCIDeviceAddressPtr in virPCIDeviceListDel()
   virhostdev.c: remove missing PCI devs from hostdev manager

  include/libvirt/libvirt-nodedev.h  |  2 +-
  src/conf/domain_audit.c|  6 +-
  src/datatypes.h|  2 +
  src/hypervisor/domain_driver.c | 30 ++
  src/hypervisor/domain_driver.h |  4 ++
  src/hypervisor/virhostdev.c| 88 ++--
  src/hypervisor/virhostdev.h|  2 +
  src/libvirt-nodedev.c  | 15 +++--
  src/libvirt_private.syms   |  3 +
  src/libxl/libxl_driver.c   | 87 
  src/node_device/node_device_udev.c | 11 ++--
  src/qemu/qemu_cgroup.c | 10 
  src/qemu/qemu_domain_address.c |  5 +-
  src/qemu/qemu_driver.c | 81 +++---
  src/security/security_apparmor.c   |  3 +-
  src/security/security_dac.c| 61 
  src/security/security_selinux.c| 66 +
  src/security/virt-aa-helper.c  |  6 +-
  src/util/virnetdev.c   |  3 +-
  src/util/virnvme.c |  5 +-
  src/util/virpci.c  | 93 ++
  src/util/virpci.h  | 14 ++---
  tests/virhostdevtest.c |  3 +-
  tests/virpcitest.c | 35 ---
  tools/virsh-domain.c   | 18 ++
  25 files changed, 325 insertions(+), 328 deletions(-)





Re: [libvirt PATCH] vircgroup: correctly free nested virCgroupPtr

2021-02-15 Thread Daniel Henrique Barboza




On 2/15/21 2:21 PM, Pavel Hrdina wrote:

Fixes: 184245f53b94fc84f727eb6e8a2aa52df02d69c0

Signed-off-by: Pavel Hrdina 
---


Reviewed-by: Daniel Henrique Barboza 


  src/util/vircgroup.c | 3 ++-
  1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c
index 57e18d6f38..abc06b8cb0 100644
--- a/src/util/vircgroup.c
+++ b/src/util/vircgroup.c
@@ -3770,7 +3770,8 @@ virCgroupFree(virCgroupPtr group)
  g_free(group->unified.mountPoint);
  g_free(group->unified.placement);
  g_free(group->unitName);
-g_free(group->nested);
+
+virCgroupFree(group->nested);
  
  g_free(group);

  }





Re: [PATCH] qemu_hotplug: Don't dereference NULL pointer @newb in qemuDomainChangeNet()

2021-02-15 Thread Daniel Henrique Barboza




On 2/15/21 2:59 PM, Michal Privoznik wrote:

In one of my previous commits I've made an attempt to restore the
noqueue qdisc on a TAP corresponding to domain's  if
QoS is cleared out. The commit consisted of two almost identical
hunks. In both the pointer is dereferenced. But in one of them,
the pointer to new bandwidth can't be NULL while in the other it
can leading to a crash.

Fixes: d53b09235398c1320ed2f1b45b640823171467ed
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1919619
Signed-off-by: Michal Privoznik 
---



Reviewed-by: Daniel Henrique Barboza 


  src/qemu/qemu_hotplug.c | 4 ++--
  1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index e7863328db..a66354426d 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -3900,10 +3900,10 @@ qemuDomainChangeNet(virQEMUDriverPtr driver,
  
  /* If the old bandwidth was cleared out, restore qdisc. */

  if (virDomainNetTypeSharesHostView(newdev)) {
-if (!newb->out || newb->out->average == 0)
+if (!newb || !newb->out || newb->out->average == 0)
  qemuDomainInterfaceSetDefaultQDisc(driver, newdev);
  } else {
-if (!newb->in || newb->in->average == 0)
+if (!newb || !newb->in || newb->in->average == 0)
  qemuDomainInterfaceSetDefaultQDisc(driver, newdev);
  }
  needReplaceDevDef = true;





Re: [libvirt PATCH 00/15] eliminate VIR_FREE in all *Dispose() functions

2021-02-04 Thread Daniel Henrique Barboza




On 2/4/21 1:38 AM, Laine Stump wrote:

A *Dispose() function is similar to a *Free() function, except that 1)
the object is always sent as a void* so it has to be typecast into
some other object-specific pointer at the top of the function, and 2)
it frees all the resources inside the object, but never frees the
object itself (this is done by the caller, somewhere deep in the
bowels of virObjectDispose or something I guess; frankly I've always
ignored the details simply "because I could").

The important point is that the contents of the object are never
referenced in any way after return from the Dispose function, so it is
unnecessary to clear any pointers, ergo (always wanted to use that
word!) it's completely safe to replace all VIR_FREEs in a *Dispose()
function with g_free (as long as there's nothing within the Dispose
function itself that depends on the pointers being cleared).

After this series is applied, there will be exactly 0 instances of
VIR_FREE in any *Dispose() (or *Free()) function. As with the *Free()
series, almost all were accomplished by directly replacing VIR_FREE
with g_free, but there were a couple oddities that needed separate
patches just to call them out:

  * Patch 1 & 2 - in both cases a Dispose() function was the only
caller to a *Free() function that didn't fit the normal pattern of
a *Free() function. Since each of the Free()s had only one caller
(their respective *Dispose() parents), their contents were just
moved into the caller, clearing the way for their VIR_FREEs to be
g_free-ified (in later patches, along with the other *Dispose()
functions in the same directories).

220 VIR_FREE uses eliminated in this series, so a total of 762 for the
two series combined (nearly 20% of all remaining VIR_FREEs).

Laine Stump (15):
   conf: simplify virDomainCapsDispose()
   rpc: eliminate static function virNetLibsshSessionAuthMethodsFree()
   bhyve: replace VIR_FREE with g_free in all *Dispose() functions
   libxl: replace VIR_FREE with g_free in all *Dispose() functions
   qemu: replace VIR_FREE with g_free in all *Dispose() functions
   interface: replace VIR_FREE with g_free in all *Dispose() functions
   access: replace VIR_FREE with g_free in all *Dispose() functions
   hypervisor: replace VIR_FREE with g_free in all *Dispose() functions
   logging: replace VIR_FREE with g_free in all *Dispose() functions
   rpc: replace VIR_FREE with g_free in all *Dispose() functions
   security: replace VIR_FREE with g_free in all *Dispose() functions
   util: replace VIR_FREE with g_free in all *Dispose() functions
   conf: replace VIR_FREE with g_free in all *Dispose() functions
   tests: replace VIR_FREE with g_free in all *Dispose() functions
   datatypes: replace VIR_FREE with g_free in all *Dispose() functions



Series LGTM, just be careful with what I mentioned in patch 10.


All patches:


Reviewed-by: Daniel Henrique Barboza 



  src/access/viraccessmanager.c   |   2 +-
  src/bhyve/bhyve_conf.c  |   2 +-
  src/conf/capabilities.c |  22 ++---
  src/conf/checkpoint_conf.c  |   2 +-
  src/conf/domain_capabilities.c  |  29 ++
  src/conf/domain_conf.c  |   2 +-
  src/conf/domain_event.c |  52 +-
  src/conf/moment_conf.c  |   6 +-
  src/conf/object_event.c |   4 +-
  src/conf/snapshot_conf.c|   4 +-
  src/conf/virsecretobj.c |   6 +-
  src/conf/virstorageobj.c|   4 +-
  src/datatypes.c |  34 +++
  src/hypervisor/virhostdev.c |   2 +-
  src/interface/interface_backend_netcf.c |   2 +-
  src/libxl/libxl_conf.c  |  20 ++--
  src/libxl/libxl_migration.c |   2 +-
  src/logging/log_handler.c   |   2 +-
  src/qemu/qemu_agent.c   |   2 +-
  src/qemu/qemu_capabilities.c|  10 +-
  src/qemu/qemu_conf.c| 122 
  src/qemu/qemu_domain.c  |  10 +-
  src/qemu/qemu_monitor.c |   4 +-
  src/rpc/virnetclient.c  |   4 +-
  src/rpc/virnetdaemon.c  |   6 +-
  src/rpc/virnetlibsshsession.c   |  37 +++
  src/rpc/virnetsaslcontext.c |   2 +-
  src/rpc/virnetserver.c  |   8 +-
  src/rpc/virnetserverservice.c   |   2 +-
  src/rpc/virnetsocket.c  |   6 +-
  src/rpc/virnetsshsession.c  |   8 +-
  src/rpc/virnettlscontext.c  |   6 +-
  src/security/security_manager.c |   2 +-
  src/util/virdnsmasq.c   |   2 +-
  src/util/virfilecache.c |   4 +-
  src/util/virmdev.c  |   2 +-
  src/util/virnvme.c  |   2 +-
  src/util/virpci.c   |   2 +-
  src/util/virresctrl.c   |

Re: [libvirt PATCH 10/15] rpc: replace VIR_FREE with g_free in all *Dispose() functions

2021-02-04 Thread Daniel Henrique Barboza

This patch does not apply cleanly. The reason:


On 2/4/21 1:38 AM, Laine Stump wrote:

Signed-off-by: Laine Stump 
---
  src/rpc/virnetclient.c|  4 ++--
  src/rpc/virnetdaemon.c|  6 +++---
  src/rpc/virnetlibsshsession.c | 18 +-
  src/rpc/virnetsaslcontext.c   |  2 +-
  src/rpc/virnetserver.c|  8 
  src/rpc/virnetserverservice.c |  2 +-
  src/rpc/virnetsocket.c|  6 +++---
  src/rpc/virnetsshsession.c|  8 
  src/rpc/virnettlscontext.c|  6 +++---
  9 files changed, 30 insertions(+), 30 deletions(-)

diff --git a/src/rpc/virnetclient.c b/src/rpc/virnetclient.c
index 2eabacd6e8..edd65941ac 100644
--- a/src/rpc/virnetclient.c
+++ b/src/rpc/virnetclient.c
@@ -747,12 +747,12 @@ void virNetClientDispose(void *obj)
  



[...]


  
  
diff --git a/src/rpc/virnetsshsession.c b/src/rpc/virnetsshsession.c

index 5bfe311544..f42aed3f62 100644
--- a/src/rpc/virnetsshsession.c
+++ b/src/rpc/virnetsshsession.c
@@ -151,10 +151,10 @@ virNetSSHSessionDispose(void *obj)
  
  virNetSSHSessionAuthMethodsClear(sess);
  
-VIR_FREE(sess->channelCommand);

-VIR_FREE(sess->hostname);
-VIR_FREE(sess->knownHostsFile);
-VIR_FREE(sess->authPath);
+g_free(sess->channelCommand);
+g_free(sess->hostname);
+g_free(sess->knownHostsFile);
+g_free(sess->authPath);
  }
  



This chunk here is referencing virNetSSHSessionAuthMethodsClear(). The name of 
the
function in the master branch is virNetSSHSessionAuthMethodsFree().

It seems to me that you had patch 24 of the previous series applied in the tree
when doing this series, and this is why the patch is considering the renamed
function.

This patch itself looks fine to me otherwise. You can either fix it to be
applicable based on master, or you can push the other series that has

"[libvirt PATCH v2 24/24] rpc: rename virNetSessionAuthMethodsFree to
virNetSessionAuthMethodsClear"

before pushing this one.


Thanks,


DHB






  static virClassPtr virNetSSHSessionClass;
diff --git a/src/rpc/virnettlscontext.c b/src/rpc/virnettlscontext.c
index 84f7e63e4d..2936b8ba57 100644
--- a/src/rpc/virnettlscontext.c
+++ b/src/rpc/virnettlscontext.c
@@ -1146,7 +1146,7 @@ void virNetTLSContextDispose(void *obj)
  PROBE(RPC_TLS_CONTEXT_DISPOSE,
"ctxt=%p", ctxt);
  
-VIR_FREE(ctxt->priority);

+g_free(ctxt->priority);
  gnutls_dh_params_deinit(ctxt->dhParams);
  gnutls_certificate_free_credentials(ctxt->x509cred);
  }
@@ -1415,8 +1415,8 @@ void virNetTLSSessionDispose(void *obj)
  PROBE(RPC_TLS_SESSION_DISPOSE,
"sess=%p", sess);
  
-VIR_FREE(sess->x509dname);

-VIR_FREE(sess->hostname);
+g_free(sess->x509dname);
+g_free(sess->hostname);
  gnutls_deinit(sess->session);
  }
  





Re: [libvirt PATCH v2 00/24] eliminate VIR_FREE in all *Free() functions

2021-02-04 Thread Daniel Henrique Barboza
rtestutils.c| 28 -
  tests/virnetdaemontest.c|  2 +-
  tests/virnetserverclienttest.c  |  2 +-
  tools/virsh-checkpoint.c|  6 +-
  tools/virsh-domain-monitor.c|  4 +-
  tools/virsh-domain.c|  2 +-
  tools/virsh-interface.c |  4 +-
  tools/virsh-network.c   |  8 +--
  tools/virsh-nodedev.c   |  4 +-
  tools/virsh-nwfilter.c  |  8 +--
  tools/virsh-pool.c  |  4 +-
  tools/virsh-secret.c|  4 +-
  tools/virsh-snapshot.c  |  6 +-
  tools/virsh-volume.c|  4 +-
  tools/vsh-table.c   | 10 +--
  tools/vsh.c         |  6 +-
  110 files changed, 557 insertions(+), 557 deletions(-)


All patches:

Reviewed-by: Daniel Henrique Barboza 







Re: [libvirt PATCH v2 22/24] qemu: pass pointers instead of copying objects for qemuFirmware*FreeContent()

2021-02-04 Thread Daniel Henrique Barboza




On 2/4/21 12:57 AM, Laine Stump wrote:

These functions all cooperate to free memory pointed to by a single
object that contains (doesn't *point to*, but acutally contains)


s/acutally/actually


several sub-objects. They were written to send copies of these
sub-objects to subordinate functions, rather than just sending
pointers to the sub-objects.

Let's change these functions to just send pointers to the objects
they're cleaning out rather than all the wasteful and pointless
copying.

Signed-off-by: Laine Stump 
---
  src/qemu/qemu_firmware.c | 32 
  1 file changed, 16 insertions(+), 16 deletions(-)

diff --git a/src/qemu/qemu_firmware.c b/src/qemu/qemu_firmware.c
index c22b1f1e9c..aad39ee038 100644
--- a/src/qemu/qemu_firmware.c
+++ b/src/qemu/qemu_firmware.c
@@ -188,47 +188,47 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC(qemuFirmwareOSInterface, 
qemuFirmwareOSInterfaceFr
  
  
  static void

-qemuFirmwareFlashFileFreeContent(qemuFirmwareFlashFile flash)
+qemuFirmwareFlashFileFreeContent(qemuFirmwareFlashFilePtr flash)
  {
-VIR_FREE(flash.filename);
-VIR_FREE(flash.format);
+VIR_FREE(flash->filename);
+VIR_FREE(flash->format);
  }
  
  
  static void

-qemuFirmwareMappingFlashFreeContent(qemuFirmwareMappingFlash flash)
+qemuFirmwareMappingFlashFreeContent(qemuFirmwareMappingFlashPtr flash)
  {
-qemuFirmwareFlashFileFreeContent(flash.executable);
-qemuFirmwareFlashFileFreeContent(flash.nvram_template);
+qemuFirmwareFlashFileFreeContent(&flash->executable);
+qemuFirmwareFlashFileFreeContent(&flash->nvram_template);
  }
  
  
  static void

-qemuFirmwareMappingKernelFreeContent(qemuFirmwareMappingKernel kernel)
+qemuFirmwareMappingKernelFreeContent(qemuFirmwareMappingKernelPtr kernel)
  {
-VIR_FREE(kernel.filename);
+VIR_FREE(kernel->filename);
  }
  
  
  static void

-qemuFirmwareMappingMemoryFreeContent(qemuFirmwareMappingMemory memory)
+qemuFirmwareMappingMemoryFreeContent(qemuFirmwareMappingMemoryPtr memory)
  {
-VIR_FREE(memory.filename);
+VIR_FREE(memory->filename);
  }
  
  
  static void

-qemuFirmwareMappingFreeContent(qemuFirmwareMapping mapping)
+qemuFirmwareMappingFreeContent(qemuFirmwareMappingPtr mapping)
  {
-switch (mapping.device) {
+switch (mapping->device) {
  case QEMU_FIRMWARE_DEVICE_FLASH:
-qemuFirmwareMappingFlashFreeContent(mapping.data.flash);
+qemuFirmwareMappingFlashFreeContent(&mapping->data.flash);
  break;
  case QEMU_FIRMWARE_DEVICE_KERNEL:
-qemuFirmwareMappingKernelFreeContent(mapping.data.kernel);
+qemuFirmwareMappingKernelFreeContent(&mapping->data.kernel);
  break;
  case QEMU_FIRMWARE_DEVICE_MEMORY:
-qemuFirmwareMappingMemoryFreeContent(mapping.data.memory);
+qemuFirmwareMappingMemoryFreeContent(&mapping->data.memory);
  break;
  case QEMU_FIRMWARE_DEVICE_NONE:
  case QEMU_FIRMWARE_DEVICE_LAST:
@@ -271,7 +271,7 @@ qemuFirmwareFree(qemuFirmwarePtr fw)
  return;
  
  qemuFirmwareOSInterfaceFree(fw->interfaces);

-qemuFirmwareMappingFreeContent(fw->mapping);
+qemuFirmwareMappingFreeContent(&fw->mapping);
  for (i = 0; i < fw->ntargets; i++)
  qemuFirmwareTargetFree(fw->targets[i]);
  g_free(fw->targets);





Re: [libvirt PATCH] qemu_validate: Allow kvm hint-dedicated on non-passthrough VMs

2021-02-03 Thread Daniel Henrique Barboza




On 1/18/21 11:43 AM, Tim Wiederhake wrote:

A VM defined similar to:
   ...
   
   
   ...
is currently invalid, as hint-dedicated is only allowed if cpu mode
is host-passthrough. This restriction is unnecessary, see
https://bugzilla.redhat.com/show_bug.cgi?id=1857671.

Signed-off-by: Tim Wiederhake 
---


Reviewed-by: Daniel Henrique Barboza 


  src/qemu/qemu_validate.c | 11 +--
  1 file changed, 1 insertion(+), 10 deletions(-)

diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c
index a060bd98ba..c58d221cf8 100644
--- a/src/qemu/qemu_validate.c
+++ b/src/qemu/qemu_validate.c
@@ -253,16 +253,6 @@ qemuValidateDomainDefFeatures(const virDomainDef *def,
  }
  break;
  
-case VIR_DOMAIN_FEATURE_KVM:

-if (def->kvm_features[VIR_DOMAIN_KVM_DEDICATED] == VIR_TRISTATE_SWITCH_ON 
&&
-(!def->cpu || def->cpu->mode != 
VIR_CPU_MODE_HOST_PASSTHROUGH)) {
-virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-   _("kvm-hint-dedicated=on is only applicable "
- "for cpu host-passthrough"));
-return -1;
-}
-break;
-
  case VIR_DOMAIN_FEATURE_VMPORT:
  if (def->features[i] != VIR_TRISTATE_SWITCH_ABSENT &&
  !virQEMUCapsSupportsVmport(qemuCaps, def)) {
@@ -335,6 +325,7 @@ qemuValidateDomainDefFeatures(const virDomainDef *def,
  }
  break;
  
+case VIR_DOMAIN_FEATURE_KVM:

  case VIR_DOMAIN_FEATURE_XEN:
  case VIR_DOMAIN_FEATURE_ACPI:
  case VIR_DOMAIN_FEATURE_PAE:





Re: [PATCH] docs: Add 'known_hosts_verify' parameter for libssh(2) connection uris

2021-02-03 Thread Daniel Henrique Barboza




On 1/29/21 9:55 AM, Jakob Meng wrote:

Parameter 'known_hosts_verify' is supported for some time now,
but it is not yet documented.

Ref.:
https://gitlab.com/libvirt/libvirt/-/blob/master/src/rpc/virnetsocket.c#L941
https://gitlab.com/libvirt/libvirt/-/blob/master/src/rpc/virnetsocket.c#L1073
---


Reviewed-by: Daniel Henrique Barboza 


  docs/uri.html.in | 17 +
  1 file changed, 17 insertions(+)

diff --git a/docs/uri.html.in b/docs/uri.html.in
index f96c2970a5..61917e77b4 100644
--- a/docs/uri.html.in
+++ b/docs/uri.html.in
@@ -421,6 +421,23 @@ Note that parameter values must be
  
   Example: known_hosts=/root/.ssh/known_hosts 

+  
+
+  known_hosts_verify
+
+ libssh2, libssh 
+
+If set to normal (default), then the user will be
+asked to accept new host keys. If set to auto, new
+host keys will be auto-accepted, but existing host keys will
+still be validated. If set to ignore, this disables
+client's strict host key checking.
+
+  
+  
+
+ Example: known_hosts_verify=ignore 
+  

  
sshauth
--
2.20.1






Re: [PATCH] qemuDomainAttachRedirdevDevice: Remove need_release variable

2021-02-03 Thread Daniel Henrique Barboza




On 2/3/21 3:18 AM, Yi Li wrote:

Get rid of the 'need_release' variable.

Signed-off-by: Yi Li 
---


Good catch. The bool was being used simply as a way to tell the cleanup
code 'do not release the address if we fail before this point'. Might
as well just "return -1" in these cases and unconditionally release the
address in the jump.


Reviewed-by: Daniel Henrique Barboza 
 


  src/qemu/qemu_hotplug.c | 10 --
  1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 882e5d2384..e07dba3c5e 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -1921,18 +1921,16 @@ int qemuDomainAttachRedirdevDevice(virQEMUDriverPtr 
driver,
  bool chardevAdded = false;
  g_autofree char *tlsAlias = NULL;
  const char *secAlias = NULL;
-bool need_release = false;
  virErrorPtr orig_err;
  
  if (qemuAssignDeviceRedirdevAlias(def, redirdev, -1) < 0)

-goto cleanup;
+return -1;
  
  if (!(charAlias = qemuAliasChardevFromDevAlias(redirdev->info.alias)))

-goto cleanup;
+return -1;
  
  if ((virDomainUSBAddressEnsure(priv->usbaddrs, &redirdev->info)) < 0)

-goto cleanup;
-need_release = true;
+return -1;
  
  if (!(devstr = qemuBuildRedirdevDevStr(def, redirdev, priv->qemuCaps)))

  goto cleanup;
@@ -1964,7 +1962,7 @@ int qemuDomainAttachRedirdevDevice(virQEMUDriverPtr 
driver,
   audit:
  virDomainAuditRedirdev(vm, redirdev, "attach", ret == 0);
   cleanup:
-if (ret < 0 && need_release)
+if (ret < 0)
  qemuDomainReleaseDeviceAddress(vm, &redirdev->info);
  return ret;
  





[PATCH v2 03/10] domain_driver.c: use g_auto* in virDomainDriverNodeDeviceReset()

2021-02-02 Thread Daniel Henrique Barboza
Reviewed-by: Ján Tomko 
Signed-off-by: Daniel Henrique Barboza 
---
 src/hypervisor/domain_driver.c | 33 -
 1 file changed, 12 insertions(+), 21 deletions(-)

diff --git a/src/hypervisor/domain_driver.c b/src/hypervisor/domain_driver.c
index 0c86fd714f..82e5587a50 100644
--- a/src/hypervisor/domain_driver.c
+++ b/src/hypervisor/domain_driver.c
@@ -375,51 +375,42 @@ int
 virDomainDriverNodeDeviceReset(virNodeDevicePtr dev,
virHostdevManagerPtr hostdevMgr)
 {
-virPCIDevicePtr pci;
+g_autoptr(virPCIDevice) pci = NULL;
 virPCIDeviceAddress devAddr;
-virNodeDeviceDefPtr def = NULL;
+g_autoptr(virNodeDeviceDef) def = NULL;
 g_autofree char *xml = NULL;
-virConnectPtr nodeconn = NULL;
-virNodeDevicePtr nodedev = NULL;
-int ret = -1;
+g_autoptr(virConnect) nodeconn = NULL;
+g_autoptr(virNodeDevice) nodedev = NULL;
 
 if (!(nodeconn = virGetConnectNodeDev()))
-goto cleanup;
+return -1;
 
 /* 'dev' is associated with virConnectPtr, so for split
  * daemons, we need to get a copy that is associated with
  * the virnodedevd daemon. */
 if (!(nodedev = virNodeDeviceLookupByName(
   nodeconn, virNodeDeviceGetName(dev
-goto cleanup;
+return -1;
 
 xml = virNodeDeviceGetXMLDesc(nodedev, 0);
 if (!xml)
-goto cleanup;
+return -1;
 
 def = virNodeDeviceDefParseString(xml, EXISTING_DEVICE, NULL);
 if (!def)
-goto cleanup;
+return -1;
 
 /* ACL check must happen against original 'dev',
  * not the new 'nodedev' we acquired */
 if (virNodeDeviceResetEnsureACL(dev->conn, def) < 0)
-goto cleanup;
+return -1;
 
 if (virDomainDriverNodeDeviceGetPCIInfo(def, &devAddr) < 0)
-goto cleanup;
+return -1;
 
 pci = virPCIDeviceNew(&devAddr);
 if (!pci)
-goto cleanup;
-
-ret = virHostdevPCINodeDeviceReset(hostdevMgr, pci);
-
-virPCIDeviceFree(pci);
- cleanup:
-virNodeDeviceDefFree(def);
-virObjectUnref(nodedev);
-virObjectUnref(nodeconn);
-return ret;
+return -1;
 
+return virHostdevPCINodeDeviceReset(hostdevMgr, pci);
 }
-- 
2.26.2



[PATCH v2 10/10] scripts/check-aclrules.py: check ACL for domain_driver.c ACL callers

2021-02-02 Thread Daniel Henrique Barboza
This script works under two specific conditions. For each opened file,
search for all functions that has ACL calls and store them, and see
if there is a vir*DriverPtr struct declared in it. For each implementation
found, check if there is an ACL verification inside it, and error out if
none was found. The script also supports the concept of stub, where another
function takes the responsibility for the ACL call instead of the
original API.

Unfortunately this is not enough to cover the new scenario we have now,
with domain_driver.c containing helper functions that execute the ACL
calls. The script does not store state between files because, until now,
it wasn't needed to - APIs and stubs and vir*DriverPtr declarations were
always in the same file. Also, the script will not check for ACL in functions
that does not belong to a vir*DriverPtr interface. What we have now in
domain_driver.c breaks both assumptions: the functions are in a different
file, and there is no vir*DriverPtr being implemented in the file that
uses these functions.

This patch changes check-aclrules.py to accomodate this scenario. The helpers
that have ACL checks are stored beforehand in aclFuncHelpers, allowing other
files to use them to recognize a stub situation. In case the current file
being analyzed is domain_driver.c itself, we'll do a manual check using
aclFuncHelpers to verify that these functions indeed have ACL checks.

Signed-off-by: Daniel Henrique Barboza 
---
 scripts/check-aclrules.py  | 25 -
 src/hypervisor/meson.build |  2 ++
 2 files changed, 26 insertions(+), 1 deletion(-)

diff --git a/scripts/check-aclrules.py b/scripts/check-aclrules.py
index 2335e8cfdd..ed6805058b 100755
--- a/scripts/check-aclrules.py
+++ b/scripts/check-aclrules.py
@@ -62,6 +62,14 @@ implpermitted = {
 "vzDomainMigrateConfirm3Params": True,
 }
 
+aclFuncHelpers = {
+"virDomainDriverNodeDeviceDetachFlags": True,
+"virDomainDriverNodeDeviceReset": True,
+"virDomainDriverNodeDeviceReAttach": True,
+}
+
+aclFuncHelperFile = "domain_driver.c"
+
 lastfile = None
 
 
@@ -136,8 +144,14 @@ def process_file(filename):
 maybefunc = None
 intable = False
 table = None
+aclHelperFileCheck = False
+
+acls = aclFuncHelpers
+
+if aclFuncHelperFile in filename:
+acls = {}
+aclHelperFileCheck = True
 
-acls = {}
 aclfilters = {}
 errs = False
 with open(filename, "r") as fh:
@@ -262,6 +276,15 @@ def process_file(filename):
 if "}" in line:
 brace = brace - 1
 
+if aclHelperFileCheck:
+for helper in aclFuncHelpers:
+if helper not in acls:
+print(("%s:%d Missing ACL check in helper function '%s'") %
+  (filename, lineno, helper),
+  file=sys.stderr)
+
+errs = True
+
 return errs
 
 
diff --git a/src/hypervisor/meson.build b/src/hypervisor/meson.build
index 32d5ab365f..70801c0820 100644
--- a/src/hypervisor/meson.build
+++ b/src/hypervisor/meson.build
@@ -5,6 +5,8 @@ hypervisor_sources = [
   'virhostdev.c',
 ]
 
+stateful_driver_source_files += files(hypervisor_sources)
+
 hypervisor_lib = static_library(
   'virt_hypervisor',
   [
-- 
2.26.2



[PATCH v2 08/10] qemu, libxl, hypervisor: use virDomainDriverNodeDeviceDetachFlags() helper

2021-02-02 Thread Daniel Henrique Barboza
libxlNodeDeviceDetachFlags() and qemuNodeDeviceDetachFlags() are mostly
equal, aside from how the virHostdevmanager pointer is retrieved and
the PCI stub driver used.

Now that the PCI stub driver verification is done early in both functions,
we can use the virDomainDriverNodeDeviceDetachFlags() helper to reduce
code duplication between them. 'driverName' is checked inside the helper
to set the appropriate stub driver.

The helper is named with the 'Flags' suffix, even when the helper itself
isn't receiving the flags from the callers, to be compliant with the
ACL function virNodeDeviceDetachFlagsEnsureACL() that is being called
inside it and was called from the original functions. Renaming the helper
would implicate in renaming REMOTE_PROC_NODE_DEVICE_DETACH_FLAGS, and all the
related structs inside remote_protocol.x, to be compliant with the ACL
rules.

This is not being checked at this moment, but we'll fix check-aclrules.py to
verify all the helpers that calls ACL functions in domain_driver.c shortly.

Reviewed-by: Ján Tomko 
Signed-off-by: Daniel Henrique Barboza 
---
 src/hypervisor/domain_driver.c | 60 ++
 src/hypervisor/domain_driver.h |  4 +++
 src/libvirt_private.syms   |  1 +
 src/libxl/libxl_driver.c   | 54 ++
 src/qemu/qemu_driver.c | 49 ++-
 5 files changed, 71 insertions(+), 97 deletions(-)

diff --git a/src/hypervisor/domain_driver.c b/src/hypervisor/domain_driver.c
index ea4c3c9466..6ee74d6dff 100644
--- a/src/hypervisor/domain_driver.c
+++ b/src/hypervisor/domain_driver.c
@@ -459,3 +459,63 @@ virDomainDriverNodeDeviceReAttach(virNodeDevicePtr dev,
 
 return virHostdevPCINodeDeviceReAttach(hostdevMgr, pci);
 }
+
+int
+virDomainDriverNodeDeviceDetachFlags(virNodeDevicePtr dev,
+ virHostdevManagerPtr hostdevMgr,
+ const char *driverName)
+{
+virPCIDevicePtr pci = NULL;
+virPCIDeviceAddress devAddr;
+int ret = -1;
+virNodeDeviceDefPtr def = NULL;
+g_autofree char *xml = NULL;
+virConnectPtr nodeconn = NULL;
+virNodeDevicePtr nodedev = NULL;
+
+if (!driverName)
+return -1;
+
+if (!(nodeconn = virGetConnectNodeDev()))
+goto cleanup;
+
+/* 'dev' is associated with virConnectPtr, so for split
+ * daemons, we need to get a copy that is associated with
+ * the virnodedevd daemon. */
+if (!(nodedev = virNodeDeviceLookupByName(nodeconn,
+  virNodeDeviceGetName(dev
+goto cleanup;
+
+xml = virNodeDeviceGetXMLDesc(nodedev, 0);
+if (!xml)
+goto cleanup;
+
+def = virNodeDeviceDefParseString(xml, EXISTING_DEVICE, NULL);
+if (!def)
+goto cleanup;
+
+/* ACL check must happen against original 'dev',
+ * not the new 'nodedev' we acquired */
+if (virNodeDeviceDetachFlagsEnsureACL(dev->conn, def) < 0)
+goto cleanup;
+
+if (virDomainDriverNodeDeviceGetPCIInfo(def, &devAddr) < 0)
+goto cleanup;
+
+pci = virPCIDeviceNew(&devAddr);
+if (!pci)
+goto cleanup;
+
+if (STREQ(driverName, "vfio"))
+virPCIDeviceSetStubDriver(pci, VIR_PCI_STUB_DRIVER_VFIO);
+else if (STREQ(driverName, "xen"))
+virPCIDeviceSetStubDriver(pci, VIR_PCI_STUB_DRIVER_XEN);
+
+ret = virHostdevPCINodeDeviceDetach(hostdevMgr, pci);
+ cleanup:
+virPCIDeviceFree(pci);
+virNodeDeviceDefFree(def);
+virObjectUnref(nodedev);
+virObjectUnref(nodeconn);
+return ret;
+}
diff --git a/src/hypervisor/domain_driver.h b/src/hypervisor/domain_driver.h
index 71eed6d5a9..a22a3ee76c 100644
--- a/src/hypervisor/domain_driver.h
+++ b/src/hypervisor/domain_driver.h
@@ -56,3 +56,7 @@ int virDomainDriverNodeDeviceReset(virNodeDevicePtr dev,
 
 int virDomainDriverNodeDeviceReAttach(virNodeDevicePtr dev,
   virHostdevManagerPtr hostdevMgr);
+
+int virDomainDriverNodeDeviceDetachFlags(virNodeDevicePtr dev,
+ virHostdevManagerPtr hostdevMgr,
+ const char *driverName);
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index ed01f79106..57622dc9a7 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1503,6 +1503,7 @@ virDomainCgroupSetupMemtune;
 virDomainDriverGenerateMachineName;
 virDomainDriverGenerateRootHash;
 virDomainDriverMergeBlkioDevice;
+virDomainDriverNodeDeviceDetachFlags;
 virDomainDriverNodeDeviceGetPCIInfo;
 virDomainDriverNodeDeviceReAttach;
 virDomainDriverNodeDeviceReset;
diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
index eadacdfb76..a644593dd9 100644
--- a/src/libxl/libxl_driver.c
+++ b/src/libxl/libxl_driver.c
@@ -5779,15 +5779,8 @@ libxlNodeDeviceDetachFlags(virNodeDevice

[PATCH v2 09/10] domain_driver.c: use g_auto* in virDomainDriverNodeDeviceDetachFlags()

2021-02-02 Thread Daniel Henrique Barboza
Reviewed-by: Ján Tomko 
Signed-off-by: Daniel Henrique Barboza 
---
 src/hypervisor/domain_driver.c | 31 ---
 1 file changed, 12 insertions(+), 19 deletions(-)

diff --git a/src/hypervisor/domain_driver.c b/src/hypervisor/domain_driver.c
index 6ee74d6dff..c08b7d46c5 100644
--- a/src/hypervisor/domain_driver.c
+++ b/src/hypervisor/domain_driver.c
@@ -465,57 +465,50 @@ virDomainDriverNodeDeviceDetachFlags(virNodeDevicePtr dev,
  virHostdevManagerPtr hostdevMgr,
  const char *driverName)
 {
-virPCIDevicePtr pci = NULL;
+g_autoptr(virPCIDevice) pci = NULL;
 virPCIDeviceAddress devAddr;
-int ret = -1;
-virNodeDeviceDefPtr def = NULL;
+g_autoptr(virNodeDeviceDef) def = NULL;
 g_autofree char *xml = NULL;
-virConnectPtr nodeconn = NULL;
-virNodeDevicePtr nodedev = NULL;
+g_autoptr(virConnect) nodeconn = NULL;
+g_autoptr(virNodeDevice) nodedev = NULL;
 
 if (!driverName)
 return -1;
 
 if (!(nodeconn = virGetConnectNodeDev()))
-goto cleanup;
+return -1;
 
 /* 'dev' is associated with virConnectPtr, so for split
  * daemons, we need to get a copy that is associated with
  * the virnodedevd daemon. */
 if (!(nodedev = virNodeDeviceLookupByName(nodeconn,
   virNodeDeviceGetName(dev
-goto cleanup;
+return -1;
 
 xml = virNodeDeviceGetXMLDesc(nodedev, 0);
 if (!xml)
-goto cleanup;
+return -1;
 
 def = virNodeDeviceDefParseString(xml, EXISTING_DEVICE, NULL);
 if (!def)
-goto cleanup;
+return -1;
 
 /* ACL check must happen against original 'dev',
  * not the new 'nodedev' we acquired */
 if (virNodeDeviceDetachFlagsEnsureACL(dev->conn, def) < 0)
-goto cleanup;
+return -1;
 
 if (virDomainDriverNodeDeviceGetPCIInfo(def, &devAddr) < 0)
-goto cleanup;
+return -1;
 
 pci = virPCIDeviceNew(&devAddr);
 if (!pci)
-goto cleanup;
+return -1;
 
 if (STREQ(driverName, "vfio"))
 virPCIDeviceSetStubDriver(pci, VIR_PCI_STUB_DRIVER_VFIO);
 else if (STREQ(driverName, "xen"))
 virPCIDeviceSetStubDriver(pci, VIR_PCI_STUB_DRIVER_XEN);
 
-ret = virHostdevPCINodeDeviceDetach(hostdevMgr, pci);
- cleanup:
-virPCIDeviceFree(pci);
-virNodeDeviceDefFree(def);
-virObjectUnref(nodedev);
-virObjectUnref(nodeconn);
-return ret;
+return virHostdevPCINodeDeviceDetach(hostdevMgr, pci);
 }
-- 
2.26.2



[PATCH v2 07/10] qemu_driver.c: validate 'driverName' earlier in qemuNodeDeviceDetachFlags()

2021-02-02 Thread Daniel Henrique Barboza
The validation of 'driverName' does not depend on any other state and can be
done right on the start of the function. We can fail earlier while avoiding
a cleanup jump.

Reviewed-by: Ján Tomko 
Signed-off-by: Daniel Henrique Barboza 
---
 src/qemu/qemu_driver.c | 41 -
 1 file changed, 20 insertions(+), 21 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 64ae8fafc0..c6ba33e4ad 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -11982,6 +11982,25 @@ qemuNodeDeviceDetachFlags(virNodeDevicePtr dev,
 
 virCheckFlags(0, -1);
 
+if (!driverName)
+driverName = "vfio";
+
+if (STREQ(driverName, "vfio") && !vfio) {
+virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
+   _("VFIO device assignment is currently not "
+ "supported on this system"));
+ return -1;
+} else if (STREQ(driverName, "kvm")) {
+virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
+   _("KVM device assignment is no longer "
+ "supported on this system"));
+return -1;
+} else {
+virReportError(VIR_ERR_INVALID_ARG,
+   _("unknown driver name '%s'"), driverName);
+return -1;
+}
+
 if (!(nodeconn = virGetConnectNodeDev()))
 goto cleanup;
 
@@ -12013,27 +12032,7 @@ qemuNodeDeviceDetachFlags(virNodeDevicePtr dev,
 if (!pci)
 goto cleanup;
 
-if (!driverName)
-driverName = "vfio";
-
-if (STREQ(driverName, "vfio")) {
-if (!vfio) {
-virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
-   _("VFIO device assignment is currently not "
- "supported on this system"));
-goto cleanup;
-}
-virPCIDeviceSetStubDriver(pci, VIR_PCI_STUB_DRIVER_VFIO);
-} else if (STREQ(driverName, "kvm")) {
-virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
-   _("KVM device assignment is no longer "
- "supported on this system"));
-goto cleanup;
-} else {
-virReportError(VIR_ERR_INVALID_ARG,
-   _("unknown driver name '%s'"), driverName);
-goto cleanup;
-}
+virPCIDeviceSetStubDriver(pci, VIR_PCI_STUB_DRIVER_VFIO);
 
 ret = virHostdevPCINodeDeviceDetach(hostdev_mgr, pci);
  cleanup:
-- 
2.26.2



[PATCH v2 06/10] libxl_driver.c: validate 'driverName' earlier in libxlNodeDeviceDetachFlags()

2021-02-02 Thread Daniel Henrique Barboza
The validation of 'driverName' does not depend on any other state and can be
done right on the start of the function. We can fail earlier while avoiding
a cleanup jump.

Reviewed-by: Ján Tomko 
Signed-off-by: Daniel Henrique Barboza 
---
 src/libxl/libxl_driver.c | 14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
index 316a6c6bf5..eadacdfb76 100644
--- a/src/libxl/libxl_driver.c
+++ b/src/libxl/libxl_driver.c
@@ -5791,6 +5791,12 @@ libxlNodeDeviceDetachFlags(virNodeDevicePtr dev,
 
 virCheckFlags(0, -1);
 
+if (driverName && STRNEQ(driverName, "xen")) {
+virReportError(VIR_ERR_INVALID_ARG,
+   _("unsupported driver name '%s'"), driverName);
+return -1;
+}
+
 if (!(nodeconn = virGetConnectNodeDev()))
 goto cleanup;
 
@@ -5822,13 +5828,7 @@ libxlNodeDeviceDetachFlags(virNodeDevicePtr dev,
 if (!pci)
 goto cleanup;
 
-if (!driverName || STREQ(driverName, "xen")) {
-virPCIDeviceSetStubDriver(pci, VIR_PCI_STUB_DRIVER_XEN);
-} else {
-virReportError(VIR_ERR_INVALID_ARG,
-   _("unsupported driver name '%s'"), driverName);
-goto cleanup;
-}
+virPCIDeviceSetStubDriver(pci, VIR_PCI_STUB_DRIVER_XEN);
 
 if (virHostdevPCINodeDeviceDetach(hostdev_mgr, pci) < 0)
 goto cleanup;
-- 
2.26.2



[PATCH v2 02/10] datatypes.h: register AUTOPTR_CLEANUP_FUNC for virNodeDevicePtr

2021-02-02 Thread Daniel Henrique Barboza
Next patch will use g_autoptr() with virNodeDevicePtr for cleanups.

Reviewed-by: Ján Tomko 
Signed-off-by: Daniel Henrique Barboza 
---
 src/datatypes.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/datatypes.h b/src/datatypes.h
index ade3779e43..7a88aba0df 100644
--- a/src/datatypes.h
+++ b/src/datatypes.h
@@ -707,6 +707,8 @@ struct _virNodeDevice {
 char *parentName;   /* parent device name */
 };
 
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(virNodeDevice, virObjectUnref);
+
 /**
  * _virSecret:
  *
-- 
2.26.2



[PATCH v2 05/10] domain_driver.c: use g_auto* in virDomainDriverNodeDeviceReAttach()

2021-02-02 Thread Daniel Henrique Barboza
Reviewed-by: Ján Tomko 
Signed-off-by: Daniel Henrique Barboza 
---
 src/hypervisor/domain_driver.c | 32 
 1 file changed, 12 insertions(+), 20 deletions(-)

diff --git a/src/hypervisor/domain_driver.c b/src/hypervisor/domain_driver.c
index c559f94348..ea4c3c9466 100644
--- a/src/hypervisor/domain_driver.c
+++ b/src/hypervisor/domain_driver.c
@@ -420,50 +420,42 @@ int
 virDomainDriverNodeDeviceReAttach(virNodeDevicePtr dev,
   virHostdevManagerPtr hostdevMgr)
 {
-virPCIDevicePtr pci = NULL;
+g_autoptr(virPCIDevice) pci = NULL;
 virPCIDeviceAddress devAddr;
-int ret = -1;
-virNodeDeviceDefPtr def = NULL;
+g_autoptr(virNodeDeviceDef) def = NULL;
 g_autofree char *xml = NULL;
-virConnectPtr nodeconn = NULL;
-virNodeDevicePtr nodedev = NULL;
+g_autoptr(virConnect) nodeconn = NULL;
+g_autoptr(virNodeDevice) nodedev = NULL;
 
 if (!(nodeconn = virGetConnectNodeDev()))
-goto cleanup;
+return -1;
 
 /* 'dev' is associated with virConnectPtr, so for split
  * daemons, we need to get a copy that is associated with
  * the virnodedevd daemon. */
 if (!(nodedev = virNodeDeviceLookupByName(
   nodeconn, virNodeDeviceGetName(dev
-goto cleanup;
+return -1;
 
 xml = virNodeDeviceGetXMLDesc(nodedev, 0);
 if (!xml)
-goto cleanup;
+return -1;
 
 def = virNodeDeviceDefParseString(xml, EXISTING_DEVICE, NULL);
 if (!def)
-goto cleanup;
+return -1;
 
 /* ACL check must happen against original 'dev',
  * not the new 'nodedev' we acquired */
 if (virNodeDeviceReAttachEnsureACL(dev->conn, def) < 0)
-goto cleanup;
+return -1;
 
 if (virDomainDriverNodeDeviceGetPCIInfo(def, &devAddr) < 0)
-goto cleanup;
+return -1;
 
 pci = virPCIDeviceNew(&devAddr);
 if (!pci)
-goto cleanup;
-
-ret = virHostdevPCINodeDeviceReAttach(hostdevMgr, pci);
+return -1;
 
-virPCIDeviceFree(pci);
- cleanup:
-virNodeDeviceDefFree(def);
-virObjectUnref(nodedev);
-virObjectUnref(nodeconn);
-return ret;
+return virHostdevPCINodeDeviceReAttach(hostdevMgr, pci);
 }
-- 
2.26.2



[PATCH v2 00/10] reduce code duplication in NodeDevice driver

2021-02-02 Thread Daniel Henrique Barboza
changes from v1:
- added Jano's R-b in patches 1-9
- Patch 08:
* clarified why the 'Flags' suffix was kept in the helper name
- (new) Patch 10: change check-aclrules to verify ACL checks in
  domain_driver.c

v1 link: 
https://www.redhat.com/archives/libvir-list/2021-February/msg00065.html 

Daniel Henrique Barboza (10):
  qemu, libxl, hypervisor: use virDomainDriverNodeDeviceReset() helper
  datatypes.h: register AUTOPTR_CLEANUP_FUNC for virNodeDevicePtr
  domain_driver.c: use g_auto* in virDomainDriverNodeDeviceReset()
  qemu, libxl, hypervisor: use virDomainDriverNodeDeviceReAttach()
helper
  domain_driver.c: use g_auto* in virDomainDriverNodeDeviceReAttach()
  libxl_driver.c: validate 'driverName' earlier in
libxlNodeDeviceDetachFlags()
  qemu_driver.c: validate 'driverName' earlier in
qemuNodeDeviceDetachFlags()
  qemu, libxl, hypervisor: use virDomainDriverNodeDeviceDetachFlags()
helper
  domain_driver.c: use g_auto* in virDomainDriverNodeDeviceDetachFlags()
  scripts/check-aclrules.py: check ACL for domain_driver.c ACL callers

 scripts/check-aclrules.py  |  25 -
 src/datatypes.h|   2 +
 src/hypervisor/domain_driver.c | 147 +
 src/hypervisor/domain_driver.h |  11 +++
 src/hypervisor/meson.build |   3 +
 src/libvirt_private.syms   |   3 +
 src/libxl/libxl_driver.c   | 164 +++--
 src/qemu/qemu_driver.c | 164 -
 8 files changed, 218 insertions(+), 301 deletions(-)

-- 
2.26.2



[PATCH v2 01/10] qemu, libxl, hypervisor: use virDomainDriverNodeDeviceReset() helper

2021-02-02 Thread Daniel Henrique Barboza
libxlNodeDeviceReset() and qemuNodeDeviceReset() are mostly equal,
differing only how the virHostdevManager pointer is retrieved.

Put the common code into virDomainDriverNodeDeviceReset() to reduce
code duplication.

Reviewed-by: Ján Tomko 
Signed-off-by: Daniel Henrique Barboza 
---
 src/hypervisor/domain_driver.c | 58 ++
 src/hypervisor/domain_driver.h |  4 +++
 src/hypervisor/meson.build |  1 +
 src/libvirt_private.syms   |  1 +
 src/libxl/libxl_driver.c   | 53 ++-
 src/qemu/qemu_driver.c | 49 ++--
 6 files changed, 70 insertions(+), 96 deletions(-)

diff --git a/src/hypervisor/domain_driver.c b/src/hypervisor/domain_driver.c
index 5b03f79833..0c86fd714f 100644
--- a/src/hypervisor/domain_driver.c
+++ b/src/hypervisor/domain_driver.c
@@ -25,6 +25,10 @@
 #include "virstring.h"
 #include "vircrypto.h"
 #include "virutil.h"
+#include "virhostdev.h"
+#include "viraccessapicheck.h"
+#include "datatypes.h"
+#include "driver.h"
 
 #define VIR_FROM_THIS VIR_FROM_DOMAIN
 
@@ -365,3 +369,57 @@ virDomainDriverNodeDeviceGetPCIInfo(virNodeDeviceDefPtr 
def,
 
 return 0;
 }
+
+
+int
+virDomainDriverNodeDeviceReset(virNodeDevicePtr dev,
+   virHostdevManagerPtr hostdevMgr)
+{
+virPCIDevicePtr pci;
+virPCIDeviceAddress devAddr;
+virNodeDeviceDefPtr def = NULL;
+g_autofree char *xml = NULL;
+virConnectPtr nodeconn = NULL;
+virNodeDevicePtr nodedev = NULL;
+int ret = -1;
+
+if (!(nodeconn = virGetConnectNodeDev()))
+goto cleanup;
+
+/* 'dev' is associated with virConnectPtr, so for split
+ * daemons, we need to get a copy that is associated with
+ * the virnodedevd daemon. */
+if (!(nodedev = virNodeDeviceLookupByName(
+  nodeconn, virNodeDeviceGetName(dev
+goto cleanup;
+
+xml = virNodeDeviceGetXMLDesc(nodedev, 0);
+if (!xml)
+goto cleanup;
+
+def = virNodeDeviceDefParseString(xml, EXISTING_DEVICE, NULL);
+if (!def)
+goto cleanup;
+
+/* ACL check must happen against original 'dev',
+ * not the new 'nodedev' we acquired */
+if (virNodeDeviceResetEnsureACL(dev->conn, def) < 0)
+goto cleanup;
+
+if (virDomainDriverNodeDeviceGetPCIInfo(def, &devAddr) < 0)
+goto cleanup;
+
+pci = virPCIDeviceNew(&devAddr);
+if (!pci)
+goto cleanup;
+
+ret = virHostdevPCINodeDeviceReset(hostdevMgr, pci);
+
+virPCIDeviceFree(pci);
+ cleanup:
+virNodeDeviceDefFree(def);
+virObjectUnref(nodedev);
+virObjectUnref(nodeconn);
+return ret;
+
+}
diff --git a/src/hypervisor/domain_driver.h b/src/hypervisor/domain_driver.h
index 86b92d0284..b690844fe5 100644
--- a/src/hypervisor/domain_driver.h
+++ b/src/hypervisor/domain_driver.h
@@ -22,6 +22,7 @@
 
 #include "domain_conf.h"
 #include "node_device_conf.h"
+#include "virhostdev.h"
 
 char *
 virDomainDriverGenerateRootHash(const char *drivername,
@@ -49,3 +50,6 @@ int 
virDomainDriverSetupPersistentDefBlkioParams(virDomainDefPtr persistentDef,
 
 int virDomainDriverNodeDeviceGetPCIInfo(virNodeDeviceDefPtr def,
 virPCIDeviceAddressPtr devAddr);
+
+int virDomainDriverNodeDeviceReset(virNodeDevicePtr dev,
+   virHostdevManagerPtr hostdevMgr);
diff --git a/src/hypervisor/meson.build b/src/hypervisor/meson.build
index 85149c683e..32d5ab365f 100644
--- a/src/hypervisor/meson.build
+++ b/src/hypervisor/meson.build
@@ -11,6 +11,7 @@ hypervisor_lib = static_library(
 hypervisor_sources,
   ],
   dependencies: [
+access_dep,
 src_dep,
   ],
   include_directories: [
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 8138780237..1f6048e3f7 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1504,6 +1504,7 @@ virDomainDriverGenerateMachineName;
 virDomainDriverGenerateRootHash;
 virDomainDriverMergeBlkioDevice;
 virDomainDriverNodeDeviceGetPCIInfo;
+virDomainDriverNodeDeviceReset;
 virDomainDriverParseBlkioDeviceStr;
 virDomainDriverSetupPersistentDefBlkioParams;
 
diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
index f480f8067e..814a6c282c 100644
--- a/src/libxl/libxl_driver.c
+++ b/src/libxl/libxl_driver.c
@@ -5910,59 +5910,12 @@ libxlNodeDeviceReAttach(virNodeDevicePtr dev)
 static int
 libxlNodeDeviceReset(virNodeDevicePtr dev)
 {
-virPCIDevicePtr pci = NULL;
-virPCIDeviceAddress devAddr;
-int ret = -1;
-virNodeDeviceDefPtr def = NULL;
-char *xml = NULL;
 libxlDriverPrivatePtr driver = dev->conn->privateData;
 virHostdevManagerPtr hostdev_mgr = driver->hostdevMgr;
-virConnectPtr nodeconn = NULL;
-virNodeDevicePtr nodedev = NULL;
-
-if (!(nodeconn = virGetC

[PATCH v2 04/10] qemu, libxl, hypervisor: use virDomainDriverNodeDeviceReAttach() helper

2021-02-02 Thread Daniel Henrique Barboza
libxlNodeDeviceReAttach() and qemuNodeDeviceReAttach() are mostly equal,
differing only how the virHostdevManager pointer is retrieved.

Put the common code into virDomainDriverNodeDeviceReAttach() to reduce
code duplication.

Reviewed-by: Ján Tomko 
Signed-off-by: Daniel Henrique Barboza 
---
 src/hypervisor/domain_driver.c | 53 ++
 src/hypervisor/domain_driver.h |  3 ++
 src/libvirt_private.syms   |  1 +
 src/libxl/libxl_driver.c   | 53 ++
 src/qemu/qemu_driver.c | 49 ++-
 5 files changed, 63 insertions(+), 96 deletions(-)

diff --git a/src/hypervisor/domain_driver.c b/src/hypervisor/domain_driver.c
index 82e5587a50..c559f94348 100644
--- a/src/hypervisor/domain_driver.c
+++ b/src/hypervisor/domain_driver.c
@@ -414,3 +414,56 @@ virDomainDriverNodeDeviceReset(virNodeDevicePtr dev,
 
 return virHostdevPCINodeDeviceReset(hostdevMgr, pci);
 }
+
+
+int
+virDomainDriverNodeDeviceReAttach(virNodeDevicePtr dev,
+  virHostdevManagerPtr hostdevMgr)
+{
+virPCIDevicePtr pci = NULL;
+virPCIDeviceAddress devAddr;
+int ret = -1;
+virNodeDeviceDefPtr def = NULL;
+g_autofree char *xml = NULL;
+virConnectPtr nodeconn = NULL;
+virNodeDevicePtr nodedev = NULL;
+
+if (!(nodeconn = virGetConnectNodeDev()))
+goto cleanup;
+
+/* 'dev' is associated with virConnectPtr, so for split
+ * daemons, we need to get a copy that is associated with
+ * the virnodedevd daemon. */
+if (!(nodedev = virNodeDeviceLookupByName(
+  nodeconn, virNodeDeviceGetName(dev
+goto cleanup;
+
+xml = virNodeDeviceGetXMLDesc(nodedev, 0);
+if (!xml)
+goto cleanup;
+
+def = virNodeDeviceDefParseString(xml, EXISTING_DEVICE, NULL);
+if (!def)
+goto cleanup;
+
+/* ACL check must happen against original 'dev',
+ * not the new 'nodedev' we acquired */
+if (virNodeDeviceReAttachEnsureACL(dev->conn, def) < 0)
+goto cleanup;
+
+if (virDomainDriverNodeDeviceGetPCIInfo(def, &devAddr) < 0)
+goto cleanup;
+
+pci = virPCIDeviceNew(&devAddr);
+if (!pci)
+goto cleanup;
+
+ret = virHostdevPCINodeDeviceReAttach(hostdevMgr, pci);
+
+virPCIDeviceFree(pci);
+ cleanup:
+virNodeDeviceDefFree(def);
+virObjectUnref(nodedev);
+virObjectUnref(nodeconn);
+return ret;
+}
diff --git a/src/hypervisor/domain_driver.h b/src/hypervisor/domain_driver.h
index b690844fe5..71eed6d5a9 100644
--- a/src/hypervisor/domain_driver.h
+++ b/src/hypervisor/domain_driver.h
@@ -53,3 +53,6 @@ int virDomainDriverNodeDeviceGetPCIInfo(virNodeDeviceDefPtr 
def,
 
 int virDomainDriverNodeDeviceReset(virNodeDevicePtr dev,
virHostdevManagerPtr hostdevMgr);
+
+int virDomainDriverNodeDeviceReAttach(virNodeDevicePtr dev,
+  virHostdevManagerPtr hostdevMgr);
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 1f6048e3f7..ed01f79106 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1504,6 +1504,7 @@ virDomainDriverGenerateMachineName;
 virDomainDriverGenerateRootHash;
 virDomainDriverMergeBlkioDevice;
 virDomainDriverNodeDeviceGetPCIInfo;
+virDomainDriverNodeDeviceReAttach;
 virDomainDriverNodeDeviceReset;
 virDomainDriverParseBlkioDeviceStr;
 virDomainDriverSetupPersistentDefBlkioParams;
diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
index 814a6c282c..316a6c6bf5 100644
--- a/src/libxl/libxl_driver.c
+++ b/src/libxl/libxl_driver.c
@@ -5852,59 +5852,12 @@ libxlNodeDeviceDettach(virNodeDevicePtr dev)
 static int
 libxlNodeDeviceReAttach(virNodeDevicePtr dev)
 {
-virPCIDevicePtr pci = NULL;
-virPCIDeviceAddress devAddr;
-int ret = -1;
-virNodeDeviceDefPtr def = NULL;
-char *xml = NULL;
 libxlDriverPrivatePtr driver = dev->conn->privateData;
 virHostdevManagerPtr hostdev_mgr = driver->hostdevMgr;
-virConnectPtr nodeconn = NULL;
-virNodeDevicePtr nodedev = NULL;
-
-if (!(nodeconn = virGetConnectNodeDev()))
-goto cleanup;
-
-/* 'dev' is associated with the QEMU virConnectPtr,
- * so for split daemons, we need to get a copy that
- * is associated with the virnodedevd daemon.
- */
-if (!(nodedev = virNodeDeviceLookupByName(
-  nodeconn, virNodeDeviceGetName(dev
-goto cleanup;
-
-xml = virNodeDeviceGetXMLDesc(nodedev, 0);
-if (!xml)
-goto cleanup;
-
-def = virNodeDeviceDefParseString(xml, EXISTING_DEVICE, NULL);
-if (!def)
-goto cleanup;
-
-/* ACL check must happen against original 'dev',
- * not the new 'nodedev' we acquired */
-if (virNodeDeviceReAttachEnsureACL(dev->conn, def) < 0)
-goto cleanup;
-
-if (virDomainDriverNodeDevic

Re: [PATCH 8/9] qemu, libxl, hypervisor: use virDomainDriverNodeDeviceDetachFlags() helper

2021-02-02 Thread Daniel Henrique Barboza




On 2/2/21 1:35 PM, Daniel P. Berrangé wrote:

The check-aclrules.py script has some logic which looks to see if
the method contains a function call that resolves to another
public API entrypoint, as a special case.

So basically we'll need to process the hypervisor_driver.c file to
extract a list of public API entrpoints with ACL checks, and then
in special case the real drivers if they call one of these shared
functions.


I'll give it a shot.


Thanks,


DHB



Re: [PATCH 8/9] qemu, libxl, hypervisor: use virDomainDriverNodeDeviceDetachFlags() helper

2021-02-02 Thread Daniel Henrique Barboza




On 2/2/21 1:35 PM, Daniel P. Berrangé wrote:

On Tue, Feb 02, 2021 at 05:32:14PM +0100, Ján Tomko wrote:

On a Tuesday in 2021, Daniel P. Berrangé wrote:

On Tue, Feb 02, 2021 at 05:18:51PM +0100, Ján Tomko wrote:

On a Monday in 2021, Daniel Henrique Barboza wrote:

libxlNodeDeviceDetachFlags() and qemuNodeDeviceDetachFlags() are mostly
equal, aside from how the virHostdevmanager pointer is retrieved and
the PCI stub driver used.

Now that the PCI stub driver verification is done early in both functions,
we can use the virDomainDriverNodeDeviceDetachFlags() helper to reduce
code duplication between them. 'driverName' is checked inside the helper
to set the appropriate stub driver.

Signed-off-by: Daniel Henrique Barboza 
---
src/hypervisor/domain_driver.c | 60 ++
src/hypervisor/domain_driver.h |  4 +++
src/libvirt_private.syms   |  1 +
src/libxl/libxl_driver.c   | 54 ++
src/qemu/qemu_driver.c | 49 ++-
5 files changed, 71 insertions(+), 97 deletions(-)

diff --git a/src/hypervisor/domain_driver.c b/src/hypervisor/domain_driver.c
index ea4c3c9466..6ee74d6dff 100644
--- a/src/hypervisor/domain_driver.c
+++ b/src/hypervisor/domain_driver.c
@@ -459,3 +459,63 @@ virDomainDriverNodeDeviceReAttach(virNodeDevicePtr dev,

 return virHostdevPCINodeDeviceReAttach(hostdevMgr, pci);
}
+
+int
+virDomainDriverNodeDeviceDetachFlags(virNodeDevicePtr dev,
+ virHostdevManagerPtr hostdevMgr,
+ const char *driverName)


This helper does not even take flags, so the only reason to keep the
'Flags' in its name is to be consistent with the driver method it
implements...


Fair point. I can remove the 'Flags' name of the helper since the flags
are now being considered by the callers.





+{
+virPCIDevicePtr pci = NULL;
+virPCIDeviceAddress devAddr;
+int ret = -1;
+virNodeDeviceDefPtr def = NULL;
+g_autofree char *xml = NULL;
+virConnectPtr nodeconn = NULL;
+virNodeDevicePtr nodedev = NULL;
+
+if (!driverName)
+return -1;
+
+if (!(nodeconn = virGetConnectNodeDev()))
+goto cleanup;
+
+/* 'dev' is associated with virConnectPtr, so for split
+ * daemons, we need to get a copy that is associated with
+ * the virnodedevd daemon. */
+if (!(nodedev = virNodeDeviceLookupByName(nodeconn,
+  virNodeDeviceGetName(dev
+goto cleanup;
+
+xml = virNodeDeviceGetXMLDesc(nodedev, 0);
+if (!xml)
+goto cleanup;
+
+def = virNodeDeviceDefParseString(xml, EXISTING_DEVICE, NULL);
+if (!def)
+goto cleanup;
+
+/* ACL check must happen against original 'dev',
+ * not the new 'nodedev' we acquired */
+if (virNodeDeviceDetachFlagsEnsureACL(dev->conn, def) < 0)
+goto cleanup;
+


... and the ACL check required.

But moving the ACL checks into src/hypervisor means they are no longer
covered by the check-aclrules check.

I'd rather keep the ACL checks repetitive in each driver than risk the
chance of missing them, but that invalidates most of these refactors.

Any ideas?


Make the check-aclrules  also validate this new source file ?



I appreciate any pointers in doing that. I haven't found any 'not horrible' way
(e.g. creating a new condition to add domain_driver.c as a valid driver 
implementation
file) of doing it in check-aclrules.py.




Thanks,


DHB






Ah, I thought they also verify that each driver method has at least one
ACL call, but we have plenty of methods that are just wrappers for
MethodFlags(..., 0);



The check-aclrules.py script has some logic which looks to see if
the method contains a function call that resolves to another
public API entrypoint, as a special case.

So basically we'll need to process the hypervisor_driver.c file to
extract a list of public API entrpoints with ACL checks, and then
in special case the real drivers if they call one of these shared
functions.



Regards,
Daniel





Re: [PATCH] conf: add realtime parameter for rtc

2021-02-01 Thread Daniel Henrique Barboza

This patch won't compile in my env:

domain_conf.c.o -c ../src/conf/domain_conf.c
In file included from /usr/lib64/glib-2.0/include/glibconfig.h:9,
 from /usr/include/glib-2.0/glib/gtypes.h:32,
 from /usr/include/glib-2.0/glib/galloca.h:32,
 from /usr/include/glib-2.0/glib.h:30,
 from ../src/util/glibcompat.h:21,
 from ../src/internal.h:30,
 from ../src/conf/domain_conf.c:30:
/usr/include/glib-2.0/glib/gmacros.h:745:53: error: size of array 
‘_GStaticAssertCompileTimeAssertion_111’ is negative
  745 | #define G_STATIC_ASSERT(expr) typedef char G_PASTE 
(_GStaticAssertCompileTimeAssertion_, __COUNTER__)[(expr) ? 1 : -1] 
G_GNUC_UNUSED
  | 
^~~
/usr/include/glib-2.0/glib/gmacros.h:735:47: note: in definition of macro 
‘G_PASTE_ARGS’
  735 | #define G_PASTE_ARGS(identifier1,identifier2) identifier1 ## identifier2
  |   ^~~
/usr/include/glib-2.0/glib/gmacros.h:745:44: note: in expansion of macro 
‘G_PASTE’
  745 | #define G_STATIC_ASSERT(expr) typedef char G_PASTE 
(_GStaticAssertCompileTimeAssertion_, __COUNTER__)[(expr) ? 1 : -1] 
G_GNUC_UNUSED
  |^~~
../src/util/virenum.h:45:5: note: in expansion of macro ‘G_STATIC_ASSERT’
   45 | G_STATIC_ASSERT(G_N_ELEMENTS(name ## TypeList) == lastVal)
  | ^~~
../src/conf/domain_conf.c:1104:1: note: in expansion of macro ‘VIR_ENUM_IMPL’
 1104 | VIR_ENUM_IMPL(virDomainTimerTrack,
  | ^
[107/1007] Compiling C object src/util/libvirt_util.a.p/virutil.c.o
ninja: build stopped: subcommand failed.


You're missing this chunk in domain_conf.h:


$ git diff
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 0a5d151150..51b1189951 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -2160,6 +2160,7 @@ typedef enum {
 VIR_DOMAIN_TIMER_TRACK_BOOT = 0,
 VIR_DOMAIN_TIMER_TRACK_GUEST,
 VIR_DOMAIN_TIMER_TRACK_WALL,
+VIR_DOMAIN_TIMER_TRACK_REALTIME,
 
 VIR_DOMAIN_TIMER_TRACK_LAST

 } virDomainTimerTrackType;



Also, I believe that since you're adding a new timer track attribute
"realtime" you'll also need to:

- change domaincommon.rng to add it as a valid timer track value
- change formatdomain.rst, section 'Time keeping' - clock - timer - track,
and add this new "realtime" value


I would also claim that you would also need a new qemuxmlargvtest.c since you're
adding a new QEMU command line option, but given that we do not have any test
for the others existing timer track command lines I'd consider this new test
good to have, but optional.


Thanks,


DHB


On 1/25/21 3:23 AM, gongwei wrote:

 Pass the parameter clock rt to qemu to ensure that the
 virtual machine is not synchronized with the host time
---
  src/conf/domain_conf.c   | 1 +
  src/qemu/qemu_command.c  | 3 +++
  src/qemu/qemu_validate.c | 1 +
  3 files changed, 5 insertions(+)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index dab4f10..c19124d 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -1106,6 +1106,7 @@ VIR_ENUM_IMPL(virDomainTimerTrack,
"boot",
"guest",
"wall",
+  "realtime",
  );
  
  VIR_ENUM_IMPL(virDomainTimerTickpolicy,

diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 1ec302d..5e09aa0 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -5947,6 +5947,9 @@ qemuBuildClockArgStr(virDomainClockDefPtr def)
  case VIR_DOMAIN_TIMER_TRACK_WALL:
  virBufferAddLit(&buf, ",clock=host");
  break;
+case VIR_DOMAIN_TIMER_TRACK_REALTIME:
+virBufferAddLit(&buf, ",clock=rt");
+break;
  }
  
  switch (def->timers[i]->tickpolicy) {

diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c
index a060bd9..d4fe40f 100644
--- a/src/qemu/qemu_validate.c
+++ b/src/qemu/qemu_validate.c
@@ -444,6 +444,7 @@ qemuValidateDomainDefClockTimers(const virDomainDef *def,
  case -1: /* unspecified - use hypervisor default */
  case VIR_DOMAIN_TIMER_TRACK_GUEST:
  case VIR_DOMAIN_TIMER_TRACK_WALL:
+case VIR_DOMAIN_TIMER_TRACK_REALTIME:
  break;
  case VIR_DOMAIN_TIMER_TRACK_BOOT:
  virReportError(VIR_ERR_CONFIG_UNSUPPORTED,





Re: [PATCH v5 1/5] migration/dirtyrate: Introduce DomainGetDirtyRateInfo API

2021-02-01 Thread Daniel Henrique Barboza

This patch is making the 'check-remote-protocol' test error out in
my env:


Ok: 305
Expected Fail:  0
Fail:   1
Unexpected Pass:0
Skipped:4
Timeout:0


The output from the failed tests:

 12/310 libvirt / check-remote_protocol 
 FAIL   0.27s (exit status 1)

--- command ---
11:55:05 LC_CTYPE='en_US.UTF-8' LANG='C' LC_ALL='' /usr/bin/python3 
/home/danielhb/kvm-project/libvirt/scripts/check-remote-protocol.py 
remote_protocol virt_remote_driver 
/home/danielhb/kvm-project/libvirt/build/src/remote/libvirt_remote_driver.a 
/usr/bin/pdwtags 
/home/danielhb/kvm-project/libvirt/build/../src/remote_protocol-structs
--- stdout ---
--- /home/danielhb/kvm-project/libvirt/build/../src/remote_protocol-structs 
2020-11-19 13:27:02.018823909 -0300
+++ -   2021-02-01 08:55:05.827296710 -0300
@@ -3162,6 +3162,17 @@
 } keys;
 u_int  flags;
 };
+struct remote_domain_get_dirty_rate_info_args {
+remote_nonnull_domain  dom;
+intsec;
+u_int  flags;
+};
+struct remote_domain_get_dirty_rate_info_ret {
+intstatus;
+int64_tdirtyRate;
+int64_tstartTime;
+intcalcTime;
+};
 enum remote_procedure {
 REMOTE_PROC_CONNECT_OPEN = 1,
 REMOTE_PROC_CONNECT_CLOSE = 2,
@@ -3588,4 +3599,5 @@
 REMOTE_PROC_DOMAIN_EVENT_MEMORY_FAILURE = 423,
 REMOTE_PROC_DOMAIN_AUTHORIZED_SSH_KEYS_GET = 424,
 REMOTE_PROC_DOMAIN_AUTHORIZED_SSH_KEYS_SET = 425,
+REMOTE_PROC_DOMAIN_GET_DIRTY_RATE_INFO   = 426,
 };
---


I'm not sure how to fix it. This error persists even if I apply all the patches,
meaning that it's not something that is being declared too early. I'm afraid
you're missing some step in the remote protocol implementation that is making
this test fail  or perhaps I'm the one messing this up.

Let's see what others will say.



Thanks,


DHB


On 2/1/21 6:55 AM, Hao Wang wrote:

Introduce DomainGetDirtyRateInfo API to get domain's memory dirty rate
info which may be expected by user in order to decide whether it's proper
to be migrated out or not. Using flags to control the action of the API:

If the VIR_DOMAIN_DIRTYRATE_CALC flag is set, this will calculate
domain's memory dirty rate within specific time.

If the VIR_DOMAIN_DIRTYRATE_QUERY flag is set, this will query the
dirty rate info calculated last time.

The VIR_DOMAIN_DIRTYRATE_DEFAULT flag is equal to both
VIR_DOMAIN_DIRTYRATE_CALC and VIR_DOMAIN_DIRTYRATE_QUERY.

Signed-off-by: Hao Wang 
Signed-off-by: Zhou Yimin 
Reviewed-by: Chuan Zheng 
---
  include/libvirt/libvirt-domain.h | 59 
  src/driver-hypervisor.h  |  7 
  src/libvirt-domain.c | 56 ++
  src/libvirt_public.syms  |  5 +++
  src/remote/remote_driver.c   |  1 +
  src/remote/remote_protocol.x | 21 +++-
  6 files changed, 148 insertions(+), 1 deletion(-)

diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h
index de2456812c..77b46c2018 100644
--- a/include/libvirt/libvirt-domain.h
+++ b/include/libvirt/libvirt-domain.h
@@ -5119,4 +5119,63 @@ int virDomainAuthorizedSSHKeysSet(virDomainPtr domain,
unsigned int nkeys,
unsigned int flags);
  
+/**

+ * virDomainDirtyRateStatus:
+ *
+ * Details on the cause of a dirty rate calculation status.
+ */
+typedef enum {
+VIR_DOMAIN_DIRTYRATE_UNSTARTED = 0, /* the dirtyrate calculation has
+   not been started */
+VIR_DOMAIN_DIRTYRATE_MEASURING = 1, /* the dirtyrate calculation is
+   measuring */
+VIR_DOMAIN_DIRTYRATE_MEASURED  = 2, /* the dirtyrate calculation is
+   completed */
+
+# ifdef VIR_ENUM_SENTINELS
+VIR_DOMAIN_DIRTYRATE_LAST
+# endif
+} virDomainDirtyRateStatus;
+
+/**
+ * virDomainDirtyRateInfo:
+ *
+ * a virDomainDirtyRateInfo is a structure filled by virDomainGetDirtyRate()
+ * and extracting dirty rate infomation for a given active Domain.
+ */
+
+typedef struct _virDomainDirtyRateInfo virDomainDirtyRateInfo;
+struct _virDomainDirtyRateInfo {
+int status; /* the status of dirtyrate calculation, one of
+   virDomainDirtyRateStatus */
+long long dirtyRate;/* the dirtyrate in MB/s */
+long long startTime;/* the start time of dirtyrate calculation */
+int calcTime;   /* the period of dirtyrate calculation */
+};
+
+/**
+ * virDomainDirtyRateInfoPtr:
+ *
+ * a virDomainDirtyRateInfoPtr is a pointer to a virDomainDirtyRateInfo 
structure.
+ */
+
+typedef virDomainDirtyRateInfo 

Re: [PATCH RESEND 00/20] handle missing SR-IOV VF hostdevs during running domains

2021-02-01 Thread Daniel Henrique Barboza

Laine,


I ended up pushing patches 1-4 and 7-8 (after applying your review
suggestions, of course) because I wanted to posted another series that
were dependent on some of these patches.

Patch 5 wasn't pushed because its first use is done on patch 06 and it
doesn't make sense to push it standalone.


Thanks,


DHB


On 1/18/21 4:53 PM, Daniel Henrique Barboza wrote:

This is the rebased version of

https://www.redhat.com/archives/libvir-list/2021-January/msg00028.html

with master at 57b1ddcaaa5b5. No changes made aside from trivial conflicts
fixes.

I also removed the military jargon from the previous subject to make it
clear what this series is doing.

Daniel Henrique Barboza (20):
   virpci, domain_audit: use virPCIDeviceAddressAsString()
   qemu, lxc: move NodeDeviceGetPCIInfo() function to domain_driver.c
   domain_driver.c: use PCI address with
 virDomainDriverNodeDeviceGetPCIInfo()
   virpci.c: simplify virPCIDeviceNew() signature
   virpci: introduce virPCIDeviceExists()
   virhostdev.c: virHostdevGetPCIHostDevice() now reports missing device
   security_selinux.c: modernize set/restore hostdev subsys label
 functions
   security_dac.c: modernize hostdev label set/restore functions
   dac, selinux: skip setting/restoring label for absent PCI devices
   libvirt-nodedev.c: remove return value from virNodeDeviceFree()
   qemu_driver.c: modernize qemuNodeDeviceReAttach()
   libxl_driver.c: modernize libxlNodeDeviceReAttach()
   virsh-domain.c: modernize cmdDetachDevice()
   virhostdev.c: add virHostdevIsPCIDevice() helper
   qemu_cgroup.c: skip absent PCI devices in qemuTeardownHostdevCgroup()
   virpci.c: use virPCIDeviceAddressPtr in virPCIDeviceListFindIndex()
   virpci.c: use virPCIDeviceAddressPtr in virPCIDeviceListFind()
   virpci.c: use virPCIDeviceAddressPtr in virPCIDeviceListSteal()
   virpci.c: use virPCIDeviceAddressPtr in virPCIDeviceListDel()
   virhostdev.c: remove missing PCI devs from hostdev manager

  include/libvirt/libvirt-nodedev.h  |  2 +-
  src/conf/domain_audit.c|  6 +-
  src/datatypes.h|  2 +
  src/hypervisor/domain_driver.c | 30 ++
  src/hypervisor/domain_driver.h |  4 ++
  src/hypervisor/virhostdev.c| 88 ++--
  src/hypervisor/virhostdev.h|  2 +
  src/libvirt-nodedev.c  | 15 +++--
  src/libvirt_private.syms   |  3 +
  src/libxl/libxl_driver.c   | 87 
  src/node_device/node_device_udev.c | 11 ++--
  src/qemu/qemu_cgroup.c | 10 
  src/qemu/qemu_domain_address.c |  5 +-
  src/qemu/qemu_driver.c | 81 +++---
  src/security/security_apparmor.c   |  3 +-
  src/security/security_dac.c| 61 
  src/security/security_selinux.c| 66 +
  src/security/virt-aa-helper.c  |  6 +-
  src/util/virnetdev.c   |  3 +-
  src/util/virnvme.c |  5 +-
  src/util/virpci.c  | 93 ++
  src/util/virpci.h  | 14 ++---
  tests/virhostdevtest.c |  3 +-
  tests/virpcitest.c | 35 ---
  tools/virsh-domain.c   | 18 ++
  25 files changed, 325 insertions(+), 328 deletions(-)





[PATCH 9/9] domain_driver.c: use g_auto* in virDomainDriverNodeDeviceDetachFlags()

2021-02-01 Thread Daniel Henrique Barboza
Signed-off-by: Daniel Henrique Barboza 
---
 src/hypervisor/domain_driver.c | 31 ---
 1 file changed, 12 insertions(+), 19 deletions(-)

diff --git a/src/hypervisor/domain_driver.c b/src/hypervisor/domain_driver.c
index 6ee74d6dff..c08b7d46c5 100644
--- a/src/hypervisor/domain_driver.c
+++ b/src/hypervisor/domain_driver.c
@@ -465,57 +465,50 @@ virDomainDriverNodeDeviceDetachFlags(virNodeDevicePtr dev,
  virHostdevManagerPtr hostdevMgr,
  const char *driverName)
 {
-virPCIDevicePtr pci = NULL;
+g_autoptr(virPCIDevice) pci = NULL;
 virPCIDeviceAddress devAddr;
-int ret = -1;
-virNodeDeviceDefPtr def = NULL;
+g_autoptr(virNodeDeviceDef) def = NULL;
 g_autofree char *xml = NULL;
-virConnectPtr nodeconn = NULL;
-virNodeDevicePtr nodedev = NULL;
+g_autoptr(virConnect) nodeconn = NULL;
+g_autoptr(virNodeDevice) nodedev = NULL;
 
 if (!driverName)
 return -1;
 
 if (!(nodeconn = virGetConnectNodeDev()))
-goto cleanup;
+return -1;
 
 /* 'dev' is associated with virConnectPtr, so for split
  * daemons, we need to get a copy that is associated with
  * the virnodedevd daemon. */
 if (!(nodedev = virNodeDeviceLookupByName(nodeconn,
   virNodeDeviceGetName(dev
-goto cleanup;
+return -1;
 
 xml = virNodeDeviceGetXMLDesc(nodedev, 0);
 if (!xml)
-goto cleanup;
+return -1;
 
 def = virNodeDeviceDefParseString(xml, EXISTING_DEVICE, NULL);
 if (!def)
-goto cleanup;
+return -1;
 
 /* ACL check must happen against original 'dev',
  * not the new 'nodedev' we acquired */
 if (virNodeDeviceDetachFlagsEnsureACL(dev->conn, def) < 0)
-goto cleanup;
+return -1;
 
 if (virDomainDriverNodeDeviceGetPCIInfo(def, &devAddr) < 0)
-goto cleanup;
+return -1;
 
 pci = virPCIDeviceNew(&devAddr);
 if (!pci)
-goto cleanup;
+return -1;
 
 if (STREQ(driverName, "vfio"))
 virPCIDeviceSetStubDriver(pci, VIR_PCI_STUB_DRIVER_VFIO);
 else if (STREQ(driverName, "xen"))
 virPCIDeviceSetStubDriver(pci, VIR_PCI_STUB_DRIVER_XEN);
 
-ret = virHostdevPCINodeDeviceDetach(hostdevMgr, pci);
- cleanup:
-virPCIDeviceFree(pci);
-virNodeDeviceDefFree(def);
-virObjectUnref(nodedev);
-virObjectUnref(nodeconn);
-return ret;
+return virHostdevPCINodeDeviceDetach(hostdevMgr, pci);
 }
-- 
2.26.2



[PATCH 0/9] reduce code duplication in NodeDevice driver

2021-02-01 Thread Daniel Henrique Barboza
Hi,

This series reduces code duplication between qemu_driver.c and
libxl_driver.c by adding common code, related to NodeDevicePtr
driver functions, into helper functions in domain_driver.c.

No functional change was made.


Daniel Henrique Barboza (9):
  qemu, libxl, hypervisor: use virDomainDriverNodeDeviceReset() helper
  datatypes.h: register AUTOPTR_CLEANUP_FUNC for virNodeDevicePtr
  domain_driver.c: use g_auto* in virDomainDriverNodeDeviceReset()
  qemu, libxl, hypervisor: use virDomainDriverNodeDeviceReAttach()
helper
  domain_driver.c: use g_auto* in virDomainDriverNodeDeviceReAttach()
  libxl_driver.c: validate 'driverName' earlier in
libxlNodeDeviceDetachFlags()
  qemu_driver.c: validate 'driverName' earlier in
qemuNodeDeviceDetachFlags()
  qemu, libxl, hypervisor: use virDomainDriverNodeDeviceDetachFlags()
helper
  domain_driver.c: use g_auto* in virDomainDriverNodeDeviceDetachFlags()

 src/datatypes.h|   2 +
 src/hypervisor/domain_driver.c | 147 +
 src/hypervisor/domain_driver.h |  11 +++
 src/hypervisor/meson.build |   1 +
 src/libvirt_private.syms   |   3 +
 src/libxl/libxl_driver.c   | 164 +++--
 src/qemu/qemu_driver.c | 164 -
 7 files changed, 192 insertions(+), 300 deletions(-)

-- 
2.26.2



[PATCH 7/9] qemu_driver.c: validate 'driverName' earlier in qemuNodeDeviceDetachFlags()

2021-02-01 Thread Daniel Henrique Barboza
The validation of 'driverName' does not depend on any other state and can be
done right on the start of the function. We can fail earlier while avoiding
a cleanup jump.

Signed-off-by: Daniel Henrique Barboza 
---
 src/qemu/qemu_driver.c | 41 -
 1 file changed, 20 insertions(+), 21 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 64ae8fafc0..c6ba33e4ad 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -11982,6 +11982,25 @@ qemuNodeDeviceDetachFlags(virNodeDevicePtr dev,
 
 virCheckFlags(0, -1);
 
+if (!driverName)
+driverName = "vfio";
+
+if (STREQ(driverName, "vfio") && !vfio) {
+virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
+   _("VFIO device assignment is currently not "
+ "supported on this system"));
+ return -1;
+} else if (STREQ(driverName, "kvm")) {
+virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
+   _("KVM device assignment is no longer "
+ "supported on this system"));
+return -1;
+} else {
+virReportError(VIR_ERR_INVALID_ARG,
+   _("unknown driver name '%s'"), driverName);
+return -1;
+}
+
 if (!(nodeconn = virGetConnectNodeDev()))
 goto cleanup;
 
@@ -12013,27 +12032,7 @@ qemuNodeDeviceDetachFlags(virNodeDevicePtr dev,
 if (!pci)
 goto cleanup;
 
-if (!driverName)
-driverName = "vfio";
-
-if (STREQ(driverName, "vfio")) {
-if (!vfio) {
-virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
-   _("VFIO device assignment is currently not "
- "supported on this system"));
-goto cleanup;
-}
-virPCIDeviceSetStubDriver(pci, VIR_PCI_STUB_DRIVER_VFIO);
-} else if (STREQ(driverName, "kvm")) {
-virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
-   _("KVM device assignment is no longer "
- "supported on this system"));
-goto cleanup;
-} else {
-virReportError(VIR_ERR_INVALID_ARG,
-   _("unknown driver name '%s'"), driverName);
-goto cleanup;
-}
+virPCIDeviceSetStubDriver(pci, VIR_PCI_STUB_DRIVER_VFIO);
 
 ret = virHostdevPCINodeDeviceDetach(hostdev_mgr, pci);
  cleanup:
-- 
2.26.2



[PATCH 8/9] qemu, libxl, hypervisor: use virDomainDriverNodeDeviceDetachFlags() helper

2021-02-01 Thread Daniel Henrique Barboza
libxlNodeDeviceDetachFlags() and qemuNodeDeviceDetachFlags() are mostly
equal, aside from how the virHostdevmanager pointer is retrieved and
the PCI stub driver used.

Now that the PCI stub driver verification is done early in both functions,
we can use the virDomainDriverNodeDeviceDetachFlags() helper to reduce
code duplication between them. 'driverName' is checked inside the helper
to set the appropriate stub driver.

Signed-off-by: Daniel Henrique Barboza 
---
 src/hypervisor/domain_driver.c | 60 ++
 src/hypervisor/domain_driver.h |  4 +++
 src/libvirt_private.syms   |  1 +
 src/libxl/libxl_driver.c   | 54 ++
 src/qemu/qemu_driver.c | 49 ++-
 5 files changed, 71 insertions(+), 97 deletions(-)

diff --git a/src/hypervisor/domain_driver.c b/src/hypervisor/domain_driver.c
index ea4c3c9466..6ee74d6dff 100644
--- a/src/hypervisor/domain_driver.c
+++ b/src/hypervisor/domain_driver.c
@@ -459,3 +459,63 @@ virDomainDriverNodeDeviceReAttach(virNodeDevicePtr dev,
 
 return virHostdevPCINodeDeviceReAttach(hostdevMgr, pci);
 }
+
+int
+virDomainDriverNodeDeviceDetachFlags(virNodeDevicePtr dev,
+ virHostdevManagerPtr hostdevMgr,
+ const char *driverName)
+{
+virPCIDevicePtr pci = NULL;
+virPCIDeviceAddress devAddr;
+int ret = -1;
+virNodeDeviceDefPtr def = NULL;
+g_autofree char *xml = NULL;
+virConnectPtr nodeconn = NULL;
+virNodeDevicePtr nodedev = NULL;
+
+if (!driverName)
+return -1;
+
+if (!(nodeconn = virGetConnectNodeDev()))
+goto cleanup;
+
+/* 'dev' is associated with virConnectPtr, so for split
+ * daemons, we need to get a copy that is associated with
+ * the virnodedevd daemon. */
+if (!(nodedev = virNodeDeviceLookupByName(nodeconn,
+  virNodeDeviceGetName(dev
+goto cleanup;
+
+xml = virNodeDeviceGetXMLDesc(nodedev, 0);
+if (!xml)
+goto cleanup;
+
+def = virNodeDeviceDefParseString(xml, EXISTING_DEVICE, NULL);
+if (!def)
+goto cleanup;
+
+/* ACL check must happen against original 'dev',
+ * not the new 'nodedev' we acquired */
+if (virNodeDeviceDetachFlagsEnsureACL(dev->conn, def) < 0)
+goto cleanup;
+
+if (virDomainDriverNodeDeviceGetPCIInfo(def, &devAddr) < 0)
+goto cleanup;
+
+pci = virPCIDeviceNew(&devAddr);
+if (!pci)
+goto cleanup;
+
+if (STREQ(driverName, "vfio"))
+virPCIDeviceSetStubDriver(pci, VIR_PCI_STUB_DRIVER_VFIO);
+else if (STREQ(driverName, "xen"))
+virPCIDeviceSetStubDriver(pci, VIR_PCI_STUB_DRIVER_XEN);
+
+ret = virHostdevPCINodeDeviceDetach(hostdevMgr, pci);
+ cleanup:
+virPCIDeviceFree(pci);
+virNodeDeviceDefFree(def);
+virObjectUnref(nodedev);
+virObjectUnref(nodeconn);
+return ret;
+}
diff --git a/src/hypervisor/domain_driver.h b/src/hypervisor/domain_driver.h
index 71eed6d5a9..a22a3ee76c 100644
--- a/src/hypervisor/domain_driver.h
+++ b/src/hypervisor/domain_driver.h
@@ -56,3 +56,7 @@ int virDomainDriverNodeDeviceReset(virNodeDevicePtr dev,
 
 int virDomainDriverNodeDeviceReAttach(virNodeDevicePtr dev,
   virHostdevManagerPtr hostdevMgr);
+
+int virDomainDriverNodeDeviceDetachFlags(virNodeDevicePtr dev,
+ virHostdevManagerPtr hostdevMgr,
+ const char *driverName);
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index ed01f79106..57622dc9a7 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1503,6 +1503,7 @@ virDomainCgroupSetupMemtune;
 virDomainDriverGenerateMachineName;
 virDomainDriverGenerateRootHash;
 virDomainDriverMergeBlkioDevice;
+virDomainDriverNodeDeviceDetachFlags;
 virDomainDriverNodeDeviceGetPCIInfo;
 virDomainDriverNodeDeviceReAttach;
 virDomainDriverNodeDeviceReset;
diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
index 7c7eeb3ad0..4fc59b2a7e 100644
--- a/src/libxl/libxl_driver.c
+++ b/src/libxl/libxl_driver.c
@@ -5779,15 +5779,8 @@ libxlNodeDeviceDetachFlags(virNodeDevicePtr dev,
const char *driverName,
unsigned int flags)
 {
-virPCIDevicePtr pci = NULL;
-virPCIDeviceAddress devAddr;
-int ret = -1;
-virNodeDeviceDefPtr def = NULL;
-char *xml = NULL;
 libxlDriverPrivatePtr driver = dev->conn->privateData;
 virHostdevManagerPtr hostdev_mgr = driver->hostdevMgr;
-virConnectPtr nodeconn = NULL;
-virNodeDevicePtr nodedev = NULL;
 
 virCheckFlags(0, -1);
 
@@ -5797,50 +5790,9 @@ libxlNodeDeviceDetachFlags(virNodeDevicePtr dev,
 return -1;
 }
 
-if (!(nodeconn = virGetConnectNodeDe

[PATCH 4/9] qemu, libxl, hypervisor: use virDomainDriverNodeDeviceReAttach() helper

2021-02-01 Thread Daniel Henrique Barboza
libxlNodeDeviceReAttach() and qemuNodeDeviceReAttach() are mostly equal,
differing only how the virHostdevManager pointer is retrieved.

Put the common code into virDomainDriverNodeDeviceReAttach() to reduce
code duplication.

Signed-off-by: Daniel Henrique Barboza 
---
 src/hypervisor/domain_driver.c | 53 ++
 src/hypervisor/domain_driver.h |  3 ++
 src/libvirt_private.syms   |  1 +
 src/libxl/libxl_driver.c   | 53 ++
 src/qemu/qemu_driver.c | 49 ++-
 5 files changed, 63 insertions(+), 96 deletions(-)

diff --git a/src/hypervisor/domain_driver.c b/src/hypervisor/domain_driver.c
index 82e5587a50..c559f94348 100644
--- a/src/hypervisor/domain_driver.c
+++ b/src/hypervisor/domain_driver.c
@@ -414,3 +414,56 @@ virDomainDriverNodeDeviceReset(virNodeDevicePtr dev,
 
 return virHostdevPCINodeDeviceReset(hostdevMgr, pci);
 }
+
+
+int
+virDomainDriverNodeDeviceReAttach(virNodeDevicePtr dev,
+  virHostdevManagerPtr hostdevMgr)
+{
+virPCIDevicePtr pci = NULL;
+virPCIDeviceAddress devAddr;
+int ret = -1;
+virNodeDeviceDefPtr def = NULL;
+g_autofree char *xml = NULL;
+virConnectPtr nodeconn = NULL;
+virNodeDevicePtr nodedev = NULL;
+
+if (!(nodeconn = virGetConnectNodeDev()))
+goto cleanup;
+
+/* 'dev' is associated with virConnectPtr, so for split
+ * daemons, we need to get a copy that is associated with
+ * the virnodedevd daemon. */
+if (!(nodedev = virNodeDeviceLookupByName(
+  nodeconn, virNodeDeviceGetName(dev
+goto cleanup;
+
+xml = virNodeDeviceGetXMLDesc(nodedev, 0);
+if (!xml)
+goto cleanup;
+
+def = virNodeDeviceDefParseString(xml, EXISTING_DEVICE, NULL);
+if (!def)
+goto cleanup;
+
+/* ACL check must happen against original 'dev',
+ * not the new 'nodedev' we acquired */
+if (virNodeDeviceReAttachEnsureACL(dev->conn, def) < 0)
+goto cleanup;
+
+if (virDomainDriverNodeDeviceGetPCIInfo(def, &devAddr) < 0)
+goto cleanup;
+
+pci = virPCIDeviceNew(&devAddr);
+if (!pci)
+goto cleanup;
+
+ret = virHostdevPCINodeDeviceReAttach(hostdevMgr, pci);
+
+virPCIDeviceFree(pci);
+ cleanup:
+virNodeDeviceDefFree(def);
+virObjectUnref(nodedev);
+virObjectUnref(nodeconn);
+return ret;
+}
diff --git a/src/hypervisor/domain_driver.h b/src/hypervisor/domain_driver.h
index b690844fe5..71eed6d5a9 100644
--- a/src/hypervisor/domain_driver.h
+++ b/src/hypervisor/domain_driver.h
@@ -53,3 +53,6 @@ int virDomainDriverNodeDeviceGetPCIInfo(virNodeDeviceDefPtr 
def,
 
 int virDomainDriverNodeDeviceReset(virNodeDevicePtr dev,
virHostdevManagerPtr hostdevMgr);
+
+int virDomainDriverNodeDeviceReAttach(virNodeDevicePtr dev,
+  virHostdevManagerPtr hostdevMgr);
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 1f6048e3f7..ed01f79106 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1504,6 +1504,7 @@ virDomainDriverGenerateMachineName;
 virDomainDriverGenerateRootHash;
 virDomainDriverMergeBlkioDevice;
 virDomainDriverNodeDeviceGetPCIInfo;
+virDomainDriverNodeDeviceReAttach;
 virDomainDriverNodeDeviceReset;
 virDomainDriverParseBlkioDeviceStr;
 virDomainDriverSetupPersistentDefBlkioParams;
diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
index 50baeb43b6..718717f14b 100644
--- a/src/libxl/libxl_driver.c
+++ b/src/libxl/libxl_driver.c
@@ -5852,59 +5852,12 @@ libxlNodeDeviceDettach(virNodeDevicePtr dev)
 static int
 libxlNodeDeviceReAttach(virNodeDevicePtr dev)
 {
-virPCIDevicePtr pci = NULL;
-virPCIDeviceAddress devAddr;
-int ret = -1;
-virNodeDeviceDefPtr def = NULL;
-char *xml = NULL;
 libxlDriverPrivatePtr driver = dev->conn->privateData;
 virHostdevManagerPtr hostdev_mgr = driver->hostdevMgr;
-virConnectPtr nodeconn = NULL;
-virNodeDevicePtr nodedev = NULL;
-
-if (!(nodeconn = virGetConnectNodeDev()))
-goto cleanup;
-
-/* 'dev' is associated with the QEMU virConnectPtr,
- * so for split daemons, we need to get a copy that
- * is associated with the virnodedevd daemon.
- */
-if (!(nodedev = virNodeDeviceLookupByName(
-  nodeconn, virNodeDeviceGetName(dev
-goto cleanup;
-
-xml = virNodeDeviceGetXMLDesc(nodedev, 0);
-if (!xml)
-goto cleanup;
-
-def = virNodeDeviceDefParseString(xml, EXISTING_DEVICE, NULL);
-if (!def)
-goto cleanup;
-
-/* ACL check must happen against original 'dev',
- * not the new 'nodedev' we acquired */
-if (virNodeDeviceReAttachEnsureACL(dev->conn, def) < 0)
-goto cleanup;
-
-if (virDomainDriverNodeDeviceGetPCIInfo(def, &devAddr) 

[PATCH 1/9] qemu, libxl, hypervisor: use virDomainDriverNodeDeviceReset() helper

2021-02-01 Thread Daniel Henrique Barboza
libxlNodeDeviceReset() and qemuNodeDeviceReset() are mostly equal,
differing only how the virHostdevManager pointer is retrieved.

Put the common code into virDomainDriverNodeDeviceReset() to reduce
code duplication.

Signed-off-by: Daniel Henrique Barboza 
---
 src/hypervisor/domain_driver.c | 58 ++
 src/hypervisor/domain_driver.h |  4 +++
 src/hypervisor/meson.build |  1 +
 src/libvirt_private.syms   |  1 +
 src/libxl/libxl_driver.c   | 53 ++-
 src/qemu/qemu_driver.c | 49 ++--
 6 files changed, 70 insertions(+), 96 deletions(-)

diff --git a/src/hypervisor/domain_driver.c b/src/hypervisor/domain_driver.c
index 5b03f79833..0c86fd714f 100644
--- a/src/hypervisor/domain_driver.c
+++ b/src/hypervisor/domain_driver.c
@@ -25,6 +25,10 @@
 #include "virstring.h"
 #include "vircrypto.h"
 #include "virutil.h"
+#include "virhostdev.h"
+#include "viraccessapicheck.h"
+#include "datatypes.h"
+#include "driver.h"
 
 #define VIR_FROM_THIS VIR_FROM_DOMAIN
 
@@ -365,3 +369,57 @@ virDomainDriverNodeDeviceGetPCIInfo(virNodeDeviceDefPtr 
def,
 
 return 0;
 }
+
+
+int
+virDomainDriverNodeDeviceReset(virNodeDevicePtr dev,
+   virHostdevManagerPtr hostdevMgr)
+{
+virPCIDevicePtr pci;
+virPCIDeviceAddress devAddr;
+virNodeDeviceDefPtr def = NULL;
+g_autofree char *xml = NULL;
+virConnectPtr nodeconn = NULL;
+virNodeDevicePtr nodedev = NULL;
+int ret = -1;
+
+if (!(nodeconn = virGetConnectNodeDev()))
+goto cleanup;
+
+/* 'dev' is associated with virConnectPtr, so for split
+ * daemons, we need to get a copy that is associated with
+ * the virnodedevd daemon. */
+if (!(nodedev = virNodeDeviceLookupByName(
+  nodeconn, virNodeDeviceGetName(dev
+goto cleanup;
+
+xml = virNodeDeviceGetXMLDesc(nodedev, 0);
+if (!xml)
+goto cleanup;
+
+def = virNodeDeviceDefParseString(xml, EXISTING_DEVICE, NULL);
+if (!def)
+goto cleanup;
+
+/* ACL check must happen against original 'dev',
+ * not the new 'nodedev' we acquired */
+if (virNodeDeviceResetEnsureACL(dev->conn, def) < 0)
+goto cleanup;
+
+if (virDomainDriverNodeDeviceGetPCIInfo(def, &devAddr) < 0)
+goto cleanup;
+
+pci = virPCIDeviceNew(&devAddr);
+if (!pci)
+goto cleanup;
+
+ret = virHostdevPCINodeDeviceReset(hostdevMgr, pci);
+
+virPCIDeviceFree(pci);
+ cleanup:
+virNodeDeviceDefFree(def);
+virObjectUnref(nodedev);
+virObjectUnref(nodeconn);
+return ret;
+
+}
diff --git a/src/hypervisor/domain_driver.h b/src/hypervisor/domain_driver.h
index 86b92d0284..b690844fe5 100644
--- a/src/hypervisor/domain_driver.h
+++ b/src/hypervisor/domain_driver.h
@@ -22,6 +22,7 @@
 
 #include "domain_conf.h"
 #include "node_device_conf.h"
+#include "virhostdev.h"
 
 char *
 virDomainDriverGenerateRootHash(const char *drivername,
@@ -49,3 +50,6 @@ int 
virDomainDriverSetupPersistentDefBlkioParams(virDomainDefPtr persistentDef,
 
 int virDomainDriverNodeDeviceGetPCIInfo(virNodeDeviceDefPtr def,
 virPCIDeviceAddressPtr devAddr);
+
+int virDomainDriverNodeDeviceReset(virNodeDevicePtr dev,
+   virHostdevManagerPtr hostdevMgr);
diff --git a/src/hypervisor/meson.build b/src/hypervisor/meson.build
index 85149c683e..32d5ab365f 100644
--- a/src/hypervisor/meson.build
+++ b/src/hypervisor/meson.build
@@ -11,6 +11,7 @@ hypervisor_lib = static_library(
 hypervisor_sources,
   ],
   dependencies: [
+access_dep,
 src_dep,
   ],
   include_directories: [
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 8138780237..1f6048e3f7 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1504,6 +1504,7 @@ virDomainDriverGenerateMachineName;
 virDomainDriverGenerateRootHash;
 virDomainDriverMergeBlkioDevice;
 virDomainDriverNodeDeviceGetPCIInfo;
+virDomainDriverNodeDeviceReset;
 virDomainDriverParseBlkioDeviceStr;
 virDomainDriverSetupPersistentDefBlkioParams;
 
diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
index 3eaf106006..50baeb43b6 100644
--- a/src/libxl/libxl_driver.c
+++ b/src/libxl/libxl_driver.c
@@ -5910,59 +5910,12 @@ libxlNodeDeviceReAttach(virNodeDevicePtr dev)
 static int
 libxlNodeDeviceReset(virNodeDevicePtr dev)
 {
-virPCIDevicePtr pci = NULL;
-virPCIDeviceAddress devAddr;
-int ret = -1;
-virNodeDeviceDefPtr def = NULL;
-char *xml = NULL;
 libxlDriverPrivatePtr driver = dev->conn->privateData;
 virHostdevManagerPtr hostdev_mgr = driver->hostdevMgr;
-virConnectPtr nodeconn = NULL;
-virNodeDevicePtr nodedev = NULL;
-
-if (!(nodeconn = virGetConnectNodeDev()))
-goto

[PATCH 6/9] libxl_driver.c: validate 'driverName' earlier in libxlNodeDeviceDetachFlags()

2021-02-01 Thread Daniel Henrique Barboza
The validation of 'driverName' does not depend on any other state and can be
done right on the start of the function. We can fail earlier while avoiding
a cleanup jump.

Signed-off-by: Daniel Henrique Barboza 
---
 src/libxl/libxl_driver.c | 14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
index 718717f14b..7c7eeb3ad0 100644
--- a/src/libxl/libxl_driver.c
+++ b/src/libxl/libxl_driver.c
@@ -5791,6 +5791,12 @@ libxlNodeDeviceDetachFlags(virNodeDevicePtr dev,
 
 virCheckFlags(0, -1);
 
+if (driverName && STRNEQ(driverName, "xen")) {
+virReportError(VIR_ERR_INVALID_ARG,
+   _("unsupported driver name '%s'"), driverName);
+return -1;
+}
+
 if (!(nodeconn = virGetConnectNodeDev()))
 goto cleanup;
 
@@ -5822,13 +5828,7 @@ libxlNodeDeviceDetachFlags(virNodeDevicePtr dev,
 if (!pci)
 goto cleanup;
 
-if (!driverName || STREQ(driverName, "xen")) {
-virPCIDeviceSetStubDriver(pci, VIR_PCI_STUB_DRIVER_XEN);
-} else {
-virReportError(VIR_ERR_INVALID_ARG,
-   _("unsupported driver name '%s'"), driverName);
-goto cleanup;
-}
+virPCIDeviceSetStubDriver(pci, VIR_PCI_STUB_DRIVER_XEN);
 
 if (virHostdevPCINodeDeviceDetach(hostdev_mgr, pci) < 0)
 goto cleanup;
-- 
2.26.2



[PATCH 2/9] datatypes.h: register AUTOPTR_CLEANUP_FUNC for virNodeDevicePtr

2021-02-01 Thread Daniel Henrique Barboza
Next patch will use g_autoptr() with virNodeDevicePtr for cleanups.

Signed-off-by: Daniel Henrique Barboza 
---
 src/datatypes.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/datatypes.h b/src/datatypes.h
index ade3779e43..7a88aba0df 100644
--- a/src/datatypes.h
+++ b/src/datatypes.h
@@ -707,6 +707,8 @@ struct _virNodeDevice {
 char *parentName;   /* parent device name */
 };
 
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(virNodeDevice, virObjectUnref);
+
 /**
  * _virSecret:
  *
-- 
2.26.2



[PATCH 5/9] domain_driver.c: use g_auto* in virDomainDriverNodeDeviceReAttach()

2021-02-01 Thread Daniel Henrique Barboza
Signed-off-by: Daniel Henrique Barboza 
---
 src/hypervisor/domain_driver.c | 32 
 1 file changed, 12 insertions(+), 20 deletions(-)

diff --git a/src/hypervisor/domain_driver.c b/src/hypervisor/domain_driver.c
index c559f94348..ea4c3c9466 100644
--- a/src/hypervisor/domain_driver.c
+++ b/src/hypervisor/domain_driver.c
@@ -420,50 +420,42 @@ int
 virDomainDriverNodeDeviceReAttach(virNodeDevicePtr dev,
   virHostdevManagerPtr hostdevMgr)
 {
-virPCIDevicePtr pci = NULL;
+g_autoptr(virPCIDevice) pci = NULL;
 virPCIDeviceAddress devAddr;
-int ret = -1;
-virNodeDeviceDefPtr def = NULL;
+g_autoptr(virNodeDeviceDef) def = NULL;
 g_autofree char *xml = NULL;
-virConnectPtr nodeconn = NULL;
-virNodeDevicePtr nodedev = NULL;
+g_autoptr(virConnect) nodeconn = NULL;
+g_autoptr(virNodeDevice) nodedev = NULL;
 
 if (!(nodeconn = virGetConnectNodeDev()))
-goto cleanup;
+return -1;
 
 /* 'dev' is associated with virConnectPtr, so for split
  * daemons, we need to get a copy that is associated with
  * the virnodedevd daemon. */
 if (!(nodedev = virNodeDeviceLookupByName(
   nodeconn, virNodeDeviceGetName(dev
-goto cleanup;
+return -1;
 
 xml = virNodeDeviceGetXMLDesc(nodedev, 0);
 if (!xml)
-goto cleanup;
+return -1;
 
 def = virNodeDeviceDefParseString(xml, EXISTING_DEVICE, NULL);
 if (!def)
-goto cleanup;
+return -1;
 
 /* ACL check must happen against original 'dev',
  * not the new 'nodedev' we acquired */
 if (virNodeDeviceReAttachEnsureACL(dev->conn, def) < 0)
-goto cleanup;
+return -1;
 
 if (virDomainDriverNodeDeviceGetPCIInfo(def, &devAddr) < 0)
-goto cleanup;
+return -1;
 
 pci = virPCIDeviceNew(&devAddr);
 if (!pci)
-goto cleanup;
-
-ret = virHostdevPCINodeDeviceReAttach(hostdevMgr, pci);
+return -1;
 
-virPCIDeviceFree(pci);
- cleanup:
-virNodeDeviceDefFree(def);
-virObjectUnref(nodedev);
-virObjectUnref(nodeconn);
-return ret;
+return virHostdevPCINodeDeviceReAttach(hostdevMgr, pci);
 }
-- 
2.26.2



[PATCH 3/9] domain_driver.c: use g_auto* in virDomainDriverNodeDeviceReset()

2021-02-01 Thread Daniel Henrique Barboza
Signed-off-by: Daniel Henrique Barboza 
---
 src/hypervisor/domain_driver.c | 33 -
 1 file changed, 12 insertions(+), 21 deletions(-)

diff --git a/src/hypervisor/domain_driver.c b/src/hypervisor/domain_driver.c
index 0c86fd714f..82e5587a50 100644
--- a/src/hypervisor/domain_driver.c
+++ b/src/hypervisor/domain_driver.c
@@ -375,51 +375,42 @@ int
 virDomainDriverNodeDeviceReset(virNodeDevicePtr dev,
virHostdevManagerPtr hostdevMgr)
 {
-virPCIDevicePtr pci;
+g_autoptr(virPCIDevice) pci = NULL;
 virPCIDeviceAddress devAddr;
-virNodeDeviceDefPtr def = NULL;
+g_autoptr(virNodeDeviceDef) def = NULL;
 g_autofree char *xml = NULL;
-virConnectPtr nodeconn = NULL;
-virNodeDevicePtr nodedev = NULL;
-int ret = -1;
+g_autoptr(virConnect) nodeconn = NULL;
+g_autoptr(virNodeDevice) nodedev = NULL;
 
 if (!(nodeconn = virGetConnectNodeDev()))
-goto cleanup;
+return -1;
 
 /* 'dev' is associated with virConnectPtr, so for split
  * daemons, we need to get a copy that is associated with
  * the virnodedevd daemon. */
 if (!(nodedev = virNodeDeviceLookupByName(
   nodeconn, virNodeDeviceGetName(dev
-goto cleanup;
+return -1;
 
 xml = virNodeDeviceGetXMLDesc(nodedev, 0);
 if (!xml)
-goto cleanup;
+return -1;
 
 def = virNodeDeviceDefParseString(xml, EXISTING_DEVICE, NULL);
 if (!def)
-goto cleanup;
+return -1;
 
 /* ACL check must happen against original 'dev',
  * not the new 'nodedev' we acquired */
 if (virNodeDeviceResetEnsureACL(dev->conn, def) < 0)
-goto cleanup;
+return -1;
 
 if (virDomainDriverNodeDeviceGetPCIInfo(def, &devAddr) < 0)
-goto cleanup;
+return -1;
 
 pci = virPCIDeviceNew(&devAddr);
 if (!pci)
-goto cleanup;
-
-ret = virHostdevPCINodeDeviceReset(hostdevMgr, pci);
-
-virPCIDeviceFree(pci);
- cleanup:
-virNodeDeviceDefFree(def);
-virObjectUnref(nodedev);
-virObjectUnref(nodeconn);
-return ret;
+return -1;
 
+return virHostdevPCINodeDeviceReset(hostdevMgr, pci);
 }
-- 
2.26.2



Re: [PATCH] virsh: Simplify @flags handing in cmdSetmem() and cmdSetmaxmem()

2021-02-01 Thread Daniel Henrique Barboza




On 1/22/21 9:28 AM, Michal Privoznik wrote:

What code tries to achieve is that if no flags were provided to
either 'setmem' or 'setmaxmem' commands then the old (no flags)
API is called to be able to communicate with older daemons.
Well, the code can be simplified a bit.

Note that with this change the old no flag version of APIs is
used more often. Previously if --current argument was given it
resulted in *Flags() version to be called even though it is not
necessary - VIR_DOMAIN_AFFECT_CURRENT is implied.

Therefore, this change in fact allows virsh to talk with broader
set of daemons.


I suggest adding in the end of the commit message something in the lines
of "No user visible changes were made", making it clear that you didn't
change the behavior of setmem and setmaxmem flags.



Reviewed-by: Daniel Henrique Barboza 




Signed-off-by: Michal Privoznik 
---
  tools/virsh-domain.c | 14 --
  1 file changed, 4 insertions(+), 10 deletions(-)

diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
index 2bb136333f..9746117bdb 100644
--- a/tools/virsh-domain.c
+++ b/tools/virsh-domain.c
@@ -9018,9 +9018,6 @@ cmdSetmem(vshControl *ctl, const vshCmd *cmd)
  flags |= VIR_DOMAIN_AFFECT_CONFIG;
  if (live)
  flags |= VIR_DOMAIN_AFFECT_LIVE;
-/* none of the options were specified */
-if (!current && !live && !config)
-flags = -1;
  
  if (!(dom = virshCommandOptDomain(ctl, cmd, NULL)))

  return false;
@@ -9037,7 +9034,7 @@ cmdSetmem(vshControl *ctl, const vshCmd *cmd)
  }
  kibibytes = VIR_DIV_UP(bytes, 1024);
  
-if (flags == -1) {

+if (flags == 0) {
  if (virDomainSetMemory(dom, kibibytes) != 0)
  ret = false;
  } else {
@@ -9090,7 +9087,7 @@ cmdSetmaxmem(vshControl *ctl, const vshCmd *cmd)
  bool config = vshCommandOptBool(cmd, "config");
  bool live = vshCommandOptBool(cmd, "live");
  bool current = vshCommandOptBool(cmd, "current");
-unsigned int flags = VIR_DOMAIN_AFFECT_CURRENT | VIR_DOMAIN_MEM_MAXIMUM;
+unsigned int flags = VIR_DOMAIN_AFFECT_CURRENT;
  
  VSH_EXCLUSIVE_OPTIONS_VAR(current, live);

  VSH_EXCLUSIVE_OPTIONS_VAR(current, config);
@@ -9099,9 +9096,6 @@ cmdSetmaxmem(vshControl *ctl, const vshCmd *cmd)
  flags |= VIR_DOMAIN_AFFECT_CONFIG;
  if (live)
  flags |= VIR_DOMAIN_AFFECT_LIVE;
-/* none of the options were specified */
-if (!current && !live && !config)
-flags = -1;
  
  if (!(dom = virshCommandOptDomain(ctl, cmd, NULL)))

  return false;
@@ -9118,13 +9112,13 @@ cmdSetmaxmem(vshControl *ctl, const vshCmd *cmd)
  }
  kibibytes = VIR_DIV_UP(bytes, 1024);
  
-if (flags == -1) {

+if (flags == 0) {
  if (virDomainSetMaxMemory(dom, kibibytes) != 0) {
  vshError(ctl, "%s", _("Unable to change MaxMemorySize"));
  ret = false;
  }
  } else {
-if (virDomainSetMemoryFlags(dom, kibibytes, flags) < 0) {
+if (virDomainSetMemoryFlags(dom, kibibytes, flags | 
VIR_DOMAIN_MEM_MAXIMUM) < 0) {
  vshError(ctl, "%s", _("Unable to change MaxMemorySize"));
  ret = false;
  }





Re: [PATCH] Increase timeout for tests and syntax-check

2021-01-29 Thread Daniel Henrique Barboza




On 1/29/21 10:04 AM, Michal Privoznik wrote:

On 1/29/21 1:30 PM, Daniel Henrique Barboza wrote:



On 1/27/21 2:59 PM, Michal Privoznik wrote:

Since we've switched to meson our tests run with a timeout (meson
uses 30 seconds as the default). However, not every machine that
builds libvirt is fast enough to run every test under 30 seconds
(each test binary has its own timeout, but still). For instance
when building a package for distro on a farm that's under load.
Or on a generally slow ARM hardware. While each developer can
tune their command line for building by adding
--timeout-multiplier=10, this is hard to do for aforementioned
build farms.

It's time to admit that not everybody has the latest, top shelf
CPU and increase the timeout.

Signed-off-by: Michal Privoznik 
---


This sure will help these build farms environments, but what about the cases
where an actual timeout means that there is something wrong with the code?
E.g. commits 46d88d8dba56 and 2ba0b7497ce7 were only possible because I was
seeing tests timing out in Power hosts when the 30 sec timeout was being
enforced.

A 120 second default timeout for the majority of the test cases is a long time.
virschematest in this laptop I use takes 2.5 sec to complete. If I do something
wrong in the code and now the test is now 4 times slower (10 sec) I will not be
able to detect it (I'll need to start keeping track or something). 


With 30 second timeout you won't detect that either. Using timeout as an indicator 
of test failure is wrong IMO. And if I were not lazy and fixed 'check-access' test 
suite then we would see instantly what tests are accessing paths in the host 
(=> depend on host configuration).


30 sec is too long for most tests :)

Let's put it this way: I don't think most of us keeps track of how much a
certain test takes to complete during our dev, and the 30 sec timeout is
a marker to see if we messed up or not. A 120 timeout is too extreme for
my dev env (and I believe most if not all of us can run the test suit without
any problems during development).


All that said, I just ran 'ninja -C build test' and verified that we don't 
provide
a total run time for all tests. We provide the time taken for all 306 tests, but
not a total. If we change the script to output the total time taken to run all
tests in the test suit, in a successful run (i.e. no failed tests), then I 
wouldn't
mind the timeout increase. I can run the test suit in master, get the total time
taken, do some coding, run again, compare the new total. This comparison will 
give
me a hint of whether something went too wrong, then I can compare the numbers 
myself
to see what happened. In this case I wouldn't mind removing all test timeouts or
increasing the timeout to help the distros or what have you.



Thanks,

DHB








You'll have to
run the test suit on your RasPi 2B to see that something went wrong because the
timeout is better tuned to your RasPI than this laptop, but then the code is 
already
upstream.


So should we make timeouts shorter then? Why is 30 seconds sweet spot?



And the tests will get more complex and will naturally take longer to complete.
Eventually this timeout might no be enough. Increase the timeout again?


Sure, why not? We adapt to newer gcc/clang/$whatever, why not timeout?

Michal





Re: [PATCH] Increase timeout for tests and syntax-check

2021-01-29 Thread Daniel Henrique Barboza




On 1/27/21 2:59 PM, Michal Privoznik wrote:

Since we've switched to meson our tests run with a timeout (meson
uses 30 seconds as the default). However, not every machine that
builds libvirt is fast enough to run every test under 30 seconds
(each test binary has its own timeout, but still). For instance
when building a package for distro on a farm that's under load.
Or on a generally slow ARM hardware. While each developer can
tune their command line for building by adding
--timeout-multiplier=10, this is hard to do for aforementioned
build farms.

It's time to admit that not everybody has the latest, top shelf
CPU and increase the timeout.

Signed-off-by: Michal Privoznik 
---


This sure will help these build farms environments, but what about the cases
where an actual timeout means that there is something wrong with the code?
E.g. commits 46d88d8dba56 and 2ba0b7497ce7 were only possible because I was
seeing tests timing out in Power hosts when the 30 sec timeout was being
enforced.

A 120 second default timeout for the majority of the test cases is a long time.
virschematest in this laptop I use takes 2.5 sec to complete. If I do something
wrong in the code and now the test is now 4 times slower (10 sec) I will not be
able to detect it (I'll need to start keeping track or something). You'll have 
to
run the test suit on your RasPi 2B to see that something went wrong because the
timeout is better tuned to your RasPI than this laptop, but then the code is 
already
upstream.

And the tests will get more complex and will naturally take longer to complete.
Eventually this timeout might no be enough. Increase the timeout again?

Meson 0.57 has support for disabling test timeout entirely with 
--timeout-multiplier=0,
disabling test timeout entirely. Can't we bump the meson version to 0.57 and
then tell the distros to use timeout-multiplier=0? That will solve the problems
for them, I keep the short timeouts for development, and we won't need to keep
bumping the test timeout once every 2 years or something because the s390x
TCG enviroment in Fedora COPR is timing out again.



Thanks,


DHB





Successfully tested on my RasPi 2B, where the top three longest test
were:

   qemuxml2argvtest  OK  142.43s
   virschematest OK  40.82s
   virnettlssessiontest  OK  38.64s

and syntax-check:

  sc_spacing-check   OK  50.26
  sc_avoid_if_before_freeOK  42.30s
  sc_prohibit_cross_inclusionOK  40.51s

  build-aux/meson.build |  1 +
  tests/meson.build | 14 ++
  2 files changed, 7 insertions(+), 8 deletions(-)

diff --git a/build-aux/meson.build b/build-aux/meson.build
index c506feefd2..e7b2db8759 100644
--- a/build-aux/meson.build
+++ b/build-aux/meson.build
@@ -44,6 +44,7 @@ if git
  potfiles_dep,
],
suite: 'syntax-check',
+  timeout: 120,
  )
endforeach
  endif
diff --git a/tests/meson.build b/tests/meson.build
index 0de0783839..702090d594 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -546,6 +546,10 @@ if conf.has('WITH_YAJL')
]
  endif
  
+# Increase the default timeout because some tests may run longer,

+# esp. on slower systems.
+timeout = 180
+
  foreach data : tests
test_sources = '@0@.c'.format(data['name'])
test_bin = executable(
@@ -577,12 +581,6 @@ foreach data : tests
  ],
  export_dynamic: true,
)
-  if data['name'] == 'qemuxml2argvtest'
-timeout = 90
-  else
-# default meson timeout
-timeout = 30
-  endif
test(data['name'], test_bin, env: tests_env, timeout: timeout)
  endforeach
  
@@ -683,7 +681,7 @@ endif
  
  foreach name : test_scripts

script = find_program(name)
-  test(name, script, env: tests_env)
+  test(name, script, env: tests_env, timeout: timeout)
  endforeach
  
  add_test_setup(

@@ -703,6 +701,6 @@ add_test_setup(
  '--suppressions=@0@'.format(meson.current_source_dir() / 
'.valgrind.supp'),
  '--error-exitcode=1',
],
-  # default timeout in meson is 30s
+  # Tests take a lot longer when run under Valgrind
timeout_multiplier: 4,
  )





Re: [PATCH] conf: rename virDomainCheckVirtioOptions

2021-01-29 Thread Daniel Henrique Barboza




On 1/29/21 8:39 AM, Boris Fiuczynski wrote:

Rename virDomainCheckVirtioOptions into
virDomainCheckVirtioOptionsAreAbent since it checks if all virtio


s/virDomainCheckVirtioOptionsAreAbent/virDomainCheckVirtioOptionsAreAbsent


options are absent. The old name was very misleading.

Signed-off-by: Boris Fiuczynski 


Reviewed-by: Daniel Henrique Barboza 


---
  src/conf/domain_validate.c | 8 
  1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c
index dd4c6e0fb3..a2f236c299 100644
--- a/src/conf/domain_validate.c
+++ b/src/conf/domain_validate.c
@@ -227,7 +227,7 @@ 
virSecurityDeviceLabelDefValidate(virSecurityDeviceLabelDefPtr *seclabels,
  
  
  static int

-virDomainCheckVirtioOptions(virDomainVirtioOptionsPtr virtio)
+virDomainCheckVirtioOptionsAreAbsent(virDomainVirtioOptionsPtr virtio)
  {
  if (!virtio)
  return 0;
@@ -316,7 +316,7 @@ virDomainDiskDefValidate(const virDomainDef *def,
  return -1;
  }
  
-if (virDomainCheckVirtioOptions(disk->virtio) < 0)

+if (virDomainCheckVirtioOptionsAreAbsent(disk->virtio) < 0)
  return -1;
  }
  
@@ -1363,7 +1363,7 @@ virDomainNetDefValidate(const virDomainNetDef *net)

  }
  
  if (!virDomainNetIsVirtioModel(net) &&

-virDomainCheckVirtioOptions(net->virtio) < 0) {
+virDomainCheckVirtioOptionsAreAbsent(net->virtio) < 0) {
  return -1;
  }
  
@@ -1513,7 +1513,7 @@ virDomainVsockDefValidate(const virDomainVsockDef *vsock)

  }
  
  if (!virDomainVsockIsVirtioModel(vsock) &&

-virDomainCheckVirtioOptions(vsock->virtio) < 0)
+virDomainCheckVirtioOptionsAreAbsent(vsock->virtio) < 0)
  return -1;
  
  return 0;






Re: [PATCH 00/10] Introduce virtio-mem model

2021-01-22 Thread Daniel Henrique Barboza




On 1/22/21 6:19 PM, David Hildenbrand wrote:



Out of curiosity: are you aware of anyone working in enabling virtio-mem
for pseries/ppc64? I'm wondering if there's some kind of architecture
limitation in Power or if it's just a lack of interest.


I remember there is interest, however:

- arm64 and x86-64 is used more frequently in applicable (cloud?) setups, so it 
has high prio
- s390x doesn‘t have any proper memory hot(un)plug, and as I have a strong 
s399x background, it‘s rather easy for me to implement
- ppc64 at least supports hot(un)plug of DIMMs

There is nothing fundamental speaking against ppc64 support AFAIR.


That's good to hear.


A block size of 16MB should be possible. I‘m planning on looking into it, 
however, there are a lot of other things on my todo list for virtio-mem.


I'm not familiar with the 'block size' concept of the virtio-mem device that 
would
allow for 16MB increments. My knowledge of the pseries kernel/QEMU is that the
guest visible memory must always be 256MiB aligned due to PAPR mechanics that
forces a memory block to be at least this size. Albeit I believe that there is
no constraints of the memory this device is providing being counted as
non-hotplugable, then in this case the alignment shouldn't be needed.

But I digress. Thanks for the insights. I'll ping some people inside IBM and
see if we have a more immediate use case for virtio-mem in Power. Perhaps
we can do some sort of collaboration with your work.



Thanks,


DHB








The QEMU code has an advanced block-size auto-detection code - e.g., querying 
from the kernel but limiting it to sane values (e.g., 512 MB on some arm64 
configurations). Maybe we can borrow some of that or even sense the block size 
via QEMU? Borrowing might be easier. :)


I guess it's a good candidate for a fancy QMP API.



One can at least query the block-size via „qom-get“, but that requires to spin 
up an QEMU instance with a virtio-mem device.




On x86-64 we are good to go with a 2MB default.



- in patch 03 it is mentioned that:

"If it wants to give more memory to the guest it changes 'requested-size' to
a bigger value, and if it wants to shrink guest memory it changes the
'requested-size' to a smaller value. Note, value of zero means that guest
should release all memory offered by the device."

Does size zero implicates the virtio-mem device unplug? Will the device still
exist in the guest even with zeroed memory, acting as a sort of 'deflated
virtio-balloon'?

Yes, the device will still exist, to be grown again later. Hotunplugging the 
device itself is not supported (yet, and also not in the near future).



Assuming that virtio-mem has low overhead in the guest when it's 'deflated',
I don't see any urgency into implementing hotunplug for this device TBH.


There are still things to be optimized in QEMU regarding virtual memory 
consumption, but that‘s more general work to be tackled within the next months. 
After that, not too much speaks against just letting the device stick around to 
provide more nemory later on demand.

Thanks!





Re: [PATCH 00/10] Introduce virtio-mem model

2021-01-22 Thread Daniel Henrique Barboza




On 1/22/21 4:54 PM, David Hildenbrand wrote:



Am 22.01.2021 um 19:53 schrieb Daniel Henrique Barboza :




On 1/22/21 9:50 AM, Michal Privoznik wrote:
Technically, this is another version of:
https://www.redhat.com/archives/libvir-list/2020-December/msg00199.html
But since virtio-pmem part is pushed now, I've reworked virtio-mem a bit
and sending it as a new series.
For curious ones, David summarized behaviour well when implementing
virtio-mem support in kernel:
https://lwn.net/Articles/755423/
For less curious ones:
   # virsh update-memory $dom --requested-size 4G
adds additional 4GiB of RAM to guest;
   # virsh update-memory $dom --requested-size 0
removes those 4GiB added earlier.
Patches are also available on my GitLab:
https://gitlab.com/MichalPrivoznik/libvirt/-/tree/virtio_mem_v3


Code LGTM:

Reviewed-by: Daniel Henrique Barboza 



Hi,

Let me answer your questions.


Thanks for the reply!






A few questions about the overall design:

- it is mentioned that 'requested-size' should respect the granularity
of the block unit, but later on the 'actual' attribute is added to track
the size that the device was expanded/shrunk. What happens if we forfeit
the granularity check of the memory increments? Will QEMU error out because
we're requesting an invalid value or it will silently size the device to a
plausible size?


QEMU will error out, stating that the request-size has to be properly aligned 
to the block-size.


'requested-size' granularity check stays then :)






- Reading the lwn article I understood that David implemented this support
for s390x as well. If that's the case, then I believe you should double
check later on what's the THP size that Z uses to be sure that it's the
same 2MiB value you're considering in patch 03.


In the near future we might see arm64 and s390x support. The latter might 
probably take a bit longer. Both are not supported yet in QEMU/kernel.


Out of curiosity: are you aware of anyone working in enabling virtio-mem
for pseries/ppc64? I'm wondering if there's some kind of architecture
limitation in Power or if it's just a lack of interest.




The QEMU code has an advanced block-size auto-detection code - e.g., querying 
from the kernel but limiting it to sane values (e.g., 512 MB on some arm64 
configurations). Maybe we can borrow some of that or even sense the block size 
via QEMU? Borrowing might be easier. :)


I guess it's a good candidate for a fancy QMP API.




On x86-64 we are good to go with a 2MB default.




- in patch 03 it is mentioned that:

"If it wants to give more memory to the guest it changes 'requested-size' to
a bigger value, and if it wants to shrink guest memory it changes the
'requested-size' to a smaller value. Note, value of zero means that guest
should release all memory offered by the device."

Does size zero implicates the virtio-mem device unplug? Will the device still
exist in the guest even with zeroed memory, acting as a sort of 'deflated
virtio-balloon'?


Yes, the device will still exist, to be grown again later. Hotunplugging the 
device itself is not supported (yet, and also not in the near future).



Assuming that virtio-mem has low overhead in the guest when it's 'deflated',
I don't see any urgency into implementing hotunplug for this device TBH.



Thanks,


DHB




Thanks!





<    1   2   3   4   5   6   7   8   9   10   >