Re: [libvirt] [PATCH 00/10] Convert secret driver to use hashed object

2016-04-16 Thread John Ferlan


On 03/02/2016 01:54 PM, John Ferlan wrote:
> This series replaces the usage of linked list in secret driver with a
> hashed object list as was suggested in the review in the last patch of
> the previous secret driver changes series:
> 
> http://www.redhat.com/archives/libvir-list/2016-February/msg01274.html
> 
> Patch 1 - starts the ball rolling
> Patch 2 - is yet another code optimization (as found in bridge_driver)
> Patches 3-8 - Add the new API's "slowly" (for review purposes)
> Patch 9 - replaces the usage of linked lists with the hashed object
> Patch 10 - moves the secretLoadAllConfigs to secret_conf
> 
> The changes are loosely modeled after both virdomainobj and network_conf
> functionality.  The real meat and potato(e)s is found in patches 5 and 9.
> Other functions should be relatively straightforward.
> 
> I've done testing of various virsh secret-* commands (both valid and invalid
> options) as well as performing driver start, stop, and reload testing.
> Each patch was built using 'check' and 'syntax-check'.
> 
> The end result is much more code in secret_conf and much less in 
> secret_driver.
> 
> John Ferlan (10):
>   secret: Move virSecretObj to secret_conf.h
>   Add secretObjFromSecret
>   secret: Add hashed virSecretObj and virSecretObjList
>   secret: Introduce virSecretObjListFindBy{UUID|Usage} support
>   secret: Introduce virSecretObjListAdd* and virSecretObjListRemove
>   secret: Introduce virSecretObjListNumOfSecrets
>   secret: Introduce virSecretObjListExport
>   secret: Introduce virSecretObjListGetUUIDs
>   secret: Use the hashed virSecretObjList
>   secret: Move and rename secretLoadAllConfigs
> 
>  src/conf/secret_conf.c | 819 
> -
>  src/conf/secret_conf.h |  76 -
>  src/libvirt_private.syms   |  11 +
>  src/secret/secret_driver.c | 647 +++
>  4 files changed, 957 insertions(+), 596 deletions(-)
> 

Ping - any chance these can be finished up?  Would it be better to
repost the entire series. It should apply cleanly as there hasn't been
changes in this space.

Tks -

John

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


[libvirt] [PATCH v2 03/12] qemu: Introduce qemuDomainHostdevPrivatePtr

2016-04-16 Thread John Ferlan
Modeled after the qemuDomainDiskPrivatePtr logic, create a privateData
pointer in the _virDomainHostdevDef to allow storage of private data
for a hypervisor in order to at least temporarily store auth/secrets
data for usage during qemuBuildCommandLine.

NB: Since the qemu_parse_command (qemuParseCommandLine) code is not
expecting to restore the auth/secret data, there's no need to add
code to handle this new structure there.

Updated copyrights for modules touched. Some didn't have updates in a
couple years even though changes have been made.

Signed-off-by: John Ferlan 
---
 src/conf/domain_conf.c| 33 +---
 src/conf/domain_conf.h|  5 -
 src/lxc/lxc_native.c  |  4 ++--
 src/qemu/qemu_domain.c| 44 +++
 src/qemu/qemu_domain.h| 13 +
 src/qemu/qemu_parse_command.c |  4 ++--
 src/vbox/vbox_common.c|  4 ++--
 src/xenconfig/xen_common.c|  4 ++--
 src/xenconfig/xen_sxpr.c  |  4 ++--
 tests/virhostdevtest.c|  3 ++-
 10 files changed, 99 insertions(+), 19 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 28248c8..07f5b26 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -2121,16 +2121,32 @@ void virDomainVideoDefFree(virDomainVideoDefPtr def)
 VIR_FREE(def);
 }
 
-virDomainHostdevDefPtr virDomainHostdevDefAlloc(void)
+
+virDomainHostdevDefPtr
+virDomainHostdevDefAlloc(virDomainXMLOptionPtr xmlopt)
 {
 virDomainHostdevDefPtr def = NULL;
 
 if (VIR_ALLOC(def) < 0 ||
-VIR_ALLOC(def->info) < 0)
+VIR_ALLOC(def->info) < 0) {
 VIR_FREE(def);
+return NULL;
+}
+
+if (xmlopt &&
+xmlopt->privateData.hostdevNew &&
+!(def->privateData = xmlopt->privateData.hostdevNew()))
+goto error;
+
 return def;
+
+ error:
+VIR_FREE(def->info);
+VIR_FREE(def);
+return NULL;
 }
 
+
 static void
 virDomainHostdevSubsysSCSIiSCSIClear(virDomainHostdevSubsysSCSIiSCSIPtr 
iscsisrc)
 {
@@ -12247,7 +12263,8 @@ virDomainVideoDefParseXML(xmlNodePtr node,
 }
 
 static virDomainHostdevDefPtr
-virDomainHostdevDefParseXML(xmlNodePtr node,
+virDomainHostdevDefParseXML(virDomainXMLOptionPtr xmlopt,
+xmlNodePtr node,
 xmlXPathContextPtr ctxt,
 virHashTablePtr bootHash,
 unsigned int flags)
@@ -12259,7 +12276,7 @@ virDomainHostdevDefParseXML(xmlNodePtr node,
 
 ctxt->node = node;
 
-if (!(def = virDomainHostdevDefAlloc()))
+if (!(def = virDomainHostdevDefAlloc(xmlopt)))
 goto error;
 
 if (mode) {
@@ -12909,8 +12926,9 @@ virDomainDeviceDefParse(const char *xmlStr,
 goto error;
 break;
 case VIR_DOMAIN_DEVICE_HOSTDEV:
-if (!(dev->data.hostdev = virDomainHostdevDefParseXML(node, ctxt,
-  NULL, flags)))
+if (!(dev->data.hostdev = virDomainHostdevDefParseXML(xmlopt, node,
+  ctxt, NULL,
+  flags)))
 goto error;
 break;
 case VIR_DOMAIN_DEVICE_CONTROLLER:
@@ -16430,7 +16448,8 @@ virDomainDefParseXML(xmlDocPtr xml,
 for (i = 0; i < n; i++) {
 virDomainHostdevDefPtr hostdev;
 
-hostdev = virDomainHostdevDefParseXML(nodes[i], ctxt, bootHash, flags);
+hostdev = virDomainHostdevDefParseXML(xmlopt, nodes[i], ctxt,
+  bootHash, flags);
 if (!hostdev)
 goto error;
 
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 1986f53..fb6a02b 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -543,6 +543,8 @@ struct _virDomainHostdevCaps {
 /* basic device for direct passthrough */
 struct _virDomainHostdevDef {
 virDomainDeviceDef parent; /* higher level Def containing this */
+virObjectPtr privateData;
+
 int mode; /* enum virDomainHostdevMode */
 int startupPolicy; /* enum virDomainStartupPolicy */
 bool managed;
@@ -2495,6 +2497,7 @@ struct _virDomainXMLPrivateDataCallbacks {
 virDomainXMLPrivateDataAllocFunc  alloc;
 virDomainXMLPrivateDataFreeFunc   free;
 virDomainXMLPrivateDataNewFuncdiskNew;
+virDomainXMLPrivateDataNewFunchostdevNew;
 virDomainXMLPrivateDataFormatFunc format;
 virDomainXMLPrivateDataParseFunc  parse;
 };
@@ -2572,7 +2575,7 @@ void virDomainMemballoonDefFree(virDomainMemballoonDefPtr 
def);
 void virDomainNVRAMDefFree(virDomainNVRAMDefPtr def);
 void virDomainWatchdogDefFree(virDomainWatchdogDefPtr def);
 void virDomainVideoDefFree(virDomainVideoDefPtr def);
-virDomainHostdevDefPtr virDomainHostdevDefAlloc(void);
+virDomainHostdevDefPtr virDomainHostdevDefAlloc(virDomainXMLOptionPtr xmlopt);
 void virDomainHostdevDefClear(virDom

[libvirt] [PATCH v2 11/12] qemu: Introduce qemuDomainSecretIV

2016-04-16 Thread John Ferlan
Add the data structure and infrastructure to support an initialization
vector (IV) secret.  The IV secret generation will need to have access
to the domain private master key, so let's make sure the prepare disk
and hostdev functions can accept that now.

Anywhere that needs to make a decision over which secret type to use
in order to fill in or use the IV secret has a switch added. In particular,
when building the command line for the network URI, create a couple of
helper functions which make the decision to add the secret info.

Signed-off-by: John Ferlan 
---
 src/qemu/qemu_command.c | 106 ++--
 src/qemu/qemu_domain.c  |  34 ++--
 src/qemu/qemu_domain.h  |  22 --
 src/qemu/qemu_hotplug.c |   6 +--
 4 files changed, 138 insertions(+), 30 deletions(-)

diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 8629c15..a8cacb3 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -606,6 +606,85 @@ qemuNetworkDriveGetPort(int protocol,
 return -1;
 }
 
+
+/* qemuBuildGeneralSecinfoURI:
+ * @uri: Pointer to the URI structure to add to
+ * @secinfo: Pointer to the secret info data (if present)
+ *
+ * If we have a secinfo, then build the command line options for
+ * the secret info for the "general" case (somewhat a misnomer since
+ * an iscsi disk is the only one with a secinfo).
+ *
+ * Returns 0 on success or if no secinfo,
+ * -1 and error message if fail to add secret information
+ */
+static int
+qemuBuildGeneralSecinfoURI(virURIPtr uri,
+   qemuDomainSecretInfoPtr secinfo)
+{
+if (!secinfo)
+return 0;
+
+switch ((qemuDomainSecretInfoType) secinfo->type) {
+case VIR_DOMAIN_SECRET_INFO_PLAIN:
+if (secinfo->s.plain.secret) {
+if (virAsprintf(&uri->user, "%s:%s",
+secinfo->s.plain.username,
+secinfo->s.plain.secret) < 0)
+return -1;
+} else {
+if (VIR_STRDUP(uri->user, secinfo->s.plain.username) < 0)
+return -1;
+}
+break;
+
+case VIR_DOMAIN_SECRET_INFO_IV:
+case VIR_DOMAIN_SECRET_INFO_LAST:
+return -1;
+}
+
+return 0;
+}
+
+
+/* qemuBuildRBDSecinfoURI:
+ * @uri: Pointer to the URI structure to add to
+ * @secinfo: Pointer to the secret info data (if present)
+ *
+ * If we have a secinfo, then build the command line options for
+ * the secret info for the RBD network storage. Assumption for this
+ * is both username and secret exist for plaintext
+ *
+ * Returns 0 on success or if no secinfo,
+ * -1 and error message if fail to add secret information
+ */
+static int
+qemuBuildRBDSecinfoURI(virBufferPtr buf,
+   qemuDomainSecretInfoPtr secinfo)
+{
+if (!secinfo) {
+virBufferAddLit(buf, ":auth_supported=none");
+return 0;
+}
+
+switch ((qemuDomainSecretInfoType) secinfo->type) {
+case VIR_DOMAIN_SECRET_INFO_PLAIN:
+virBufferEscape(buf, '\\', ":", ":id=%s",
+secinfo->s.plain.username);
+virBufferEscape(buf, '\\', ":",
+":key=%s:auth_supported=cephx\\;none",
+secinfo->s.plain.secret);
+break;
+
+case VIR_DOMAIN_SECRET_INFO_IV:
+case VIR_DOMAIN_SECRET_INFO_LAST:
+return -1;
+}
+
+return 0;
+}
+
+
 #define QEMU_DEFAULT_NBD_PORT "10809"
 
 static char *
@@ -701,7 +780,8 @@ qemuBuildNetworkDriveURI(virStorageSourcePtr src,
 goto cleanup;
 }
 
-if ((uri->port = qemuNetworkDriveGetPort(src->protocol, 
src->hosts->port)) < 0)
+if ((uri->port = qemuNetworkDriveGetPort(src->protocol,
+ src->hosts->port)) < 0)
 goto cleanup;
 
 if (src->path) {
@@ -721,17 +801,8 @@ qemuBuildNetworkDriveURI(virStorageSourcePtr src,
 virAsprintf(&uri->query, "socket=%s", src->hosts->socket) < 0)
 goto cleanup;
 
-if (secinfo) {
-if (secinfo->s.plain.secret) {
-if (virAsprintf(&uri->user, "%s:%s",
-secinfo->s.plain.username,
-secinfo->s.plain.secret) < 0)
-goto cleanup;
-} else {
-if (VIR_STRDUP(uri->user, secinfo->s.plain.username) < 0)
-goto cleanup;
-}
-}
+if (qemuBuildGeneralSecinfoURI(uri, secinfo) < 0)
+goto cleanup;
 
 if (VIR_STRDUP(uri->server, src->hosts->name) < 0)
 goto cleanup;
@@ -777,15 +848,8 @@ qemuBuildNetworkDriveURI(virStorageSourcePtr src,
 if (src->snapshot)
 virBufferEscape(&buf, '\\', ":", "@%s", src->snapshot);
 
-if (secinfo) {
-virBufferEs

[libvirt] [PATCH v2 06/12] qemu: hotplug: Assume support for -device for attach virtio disk

2016-04-16 Thread John Ferlan
Since support for QEMU_CAPS_DEVICE is not assumed, let's drop the legacy
code to make life easier going forward.

Signed-off-by: John Ferlan 
---
 src/qemu/qemu_hotplug.c | 79 +
 1 file changed, 33 insertions(+), 46 deletions(-)

diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 94c0222..11efd7b 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -317,7 +317,6 @@ qemuDomainAttachVirtioDiskDevice(virConnectPtr conn,
  virDomainDiskDefPtr disk)
 {
 int ret = -1;
-const char* type = virDomainDiskBusTypeToString(disk->bus);
 qemuDomainObjPrivatePtr priv = vm->privateData;
 char *devstr = NULL;
 char *drivestr = NULL;
@@ -341,62 +340,50 @@ qemuDomainAttachVirtioDiskDevice(virConnectPtr conn,
 if (qemuDomainPrepareDisk(driver, vm, disk, NULL, false) < 0)
 goto cleanup;
 
-if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
-if (disk->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW) {
-if (virDomainCCWAddressAssign(&disk->info, priv->ccwaddrs,
-  !disk->info.addr.ccw.assigned) < 0)
-goto error;
-} else if (!disk->info.type ||
-disk->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
-if (virDomainPCIAddressEnsureAddr(priv->pciaddrs, &disk->info) < 0)
-goto error;
-}
-releaseaddr = true;
-if (qemuAssignDeviceDiskAlias(vm->def, disk, priv->qemuCaps) < 0)
+if (disk->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW) {
+if (virDomainCCWAddressAssign(&disk->info, priv->ccwaddrs,
+  !disk->info.addr.ccw.assigned) < 0)
 goto error;
-
-if (qemuDomainSecretDiskPrepare(conn, disk) < 0)
+} else if (!disk->info.type ||
+disk->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
+if (virDomainPCIAddressEnsureAddr(priv->pciaddrs, &disk->info) < 0)
 goto error;
+}
+releaseaddr = true;
+if (qemuAssignDeviceDiskAlias(vm->def, disk, priv->qemuCaps) < 0)
+goto error;
 
-if (!(drivestr = qemuBuildDriveStr(disk, false, priv->qemuCaps)))
-goto error;
+if (qemuDomainSecretDiskPrepare(conn, disk) < 0)
+goto error;
 
-if (!(drivealias = qemuDeviceDriveHostAlias(disk, priv->qemuCaps)))
-goto error;
+if (!(drivestr = qemuBuildDriveStr(disk, false, priv->qemuCaps)))
+goto error;
 
-if (!(devstr = qemuBuildDriveDevStr(vm->def, disk, 0, priv->qemuCaps)))
-goto error;
-}
+if (!(drivealias = qemuDeviceDriveHostAlias(disk, priv->qemuCaps)))
+goto error;
+
+if (!(devstr = qemuBuildDriveDevStr(vm->def, disk, 0, priv->qemuCaps)))
+goto error;
 
 if (VIR_REALLOC_N(vm->def->disks, vm->def->ndisks+1) < 0)
 goto error;
 
 qemuDomainObjEnterMonitor(driver, vm);
-if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
-ret = qemuMonitorAddDrive(priv->mon, drivestr);
-if (ret == 0) {
-ret = qemuMonitorAddDevice(priv->mon, devstr);
-if (ret < 0) {
-virErrorPtr orig_err = virSaveLastError();
-if (!drivealias ||
-qemuMonitorDriveDel(priv->mon, drivealias) < 0) {
-VIR_WARN("Unable to remove drive %s (%s) after failed "
- "qemuMonitorAddDevice",
- NULLSTR(drivealias), drivestr);
-}
-if (orig_err) {
-virSetError(orig_err);
-virFreeError(orig_err);
-}
+ret = qemuMonitorAddDrive(priv->mon, drivestr);
+if (ret == 0) {
+ret = qemuMonitorAddDevice(priv->mon, devstr);
+if (ret < 0) {
+virErrorPtr orig_err = virSaveLastError();
+if (!drivealias ||
+qemuMonitorDriveDel(priv->mon, drivealias) < 0) {
+VIR_WARN("Unable to remove drive %s (%s) after failed "
+ "qemuMonitorAddDevice",
+ NULLSTR(drivealias), drivestr);
+}
+if (orig_err) {
+virSetError(orig_err);
+virFreeError(orig_err);
 }
-}
-} else if (!disk->info.type ||
-disk->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
-virDevicePCIAddress guestAddr = disk->info.addr.pci;
-ret = qemuMonitorAddPCIDisk(priv->mon, src, type, &guestAddr);
-if (ret == 0) {
-disk->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
-memcpy(&disk->info.addr.pci, &guestAddr, sizeof(guestAddr));
 }
 }
 if (qemuDomainObjExitMonitor(driver, vm) < 0) {
-- 
2.5.5

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

[libvirt] [PATCH v2 08/12] qemu: hotplug: Adjust error path for attach virtio disk

2016-04-16 Thread John Ferlan
Adjust error path logic to make it clearer how to undo the failed add.

Signed-off-by: John Ferlan 
---
 src/qemu/qemu_hotplug.c | 55 -
 1 file changed, 32 insertions(+), 23 deletions(-)

diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index ae314be..17a70a3 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -318,6 +318,7 @@ qemuDomainAttachVirtioDiskDevice(virConnectPtr conn,
 {
 int ret = -1;
 qemuDomainObjPrivatePtr priv = vm->privateData;
+virErrorPtr orig_err;
 char *devstr = NULL;
 char *drivestr = NULL;
 char *drivealias = NULL;
@@ -368,36 +369,24 @@ qemuDomainAttachVirtioDiskDevice(virConnectPtr conn,
 if (VIR_REALLOC_N(vm->def->disks, vm->def->ndisks+1) < 0)
 goto error;
 
+/* Attach the device - 2 step process */
 qemuDomainObjEnterMonitor(driver, vm);
-ret = qemuMonitorAddDrive(priv->mon, drivestr);
-if (ret == 0) {
-ret = qemuMonitorAddDevice(priv->mon, devstr);
-if (ret < 0) {
-virErrorPtr orig_err = virSaveLastError();
-if (!drivealias ||
-qemuMonitorDriveDel(priv->mon, drivealias) < 0) {
-VIR_WARN("Unable to remove drive %s (%s) after failed "
- "qemuMonitorAddDevice",
- NULLSTR(drivealias), drivestr);
-}
-if (orig_err) {
-virSetError(orig_err);
-virFreeError(orig_err);
-}
-}
-}
+
+if (qemuMonitorAddDrive(priv->mon, drivestr) < 0)
+goto failadddrive;
+
+if (qemuMonitorAddDevice(priv->mon, devstr) < 0)
+goto failadddevice;
+
 if (qemuDomainObjExitMonitor(driver, vm) < 0) {
 releaseaddr = false;
-ret = -1;
-goto error;
+goto failexitmonitor;
 }
 
-virDomainAuditDisk(vm, NULL, disk->src, "attach", ret >= 0);
-
-if (ret < 0)
-goto error;
+virDomainAuditDisk(vm, NULL, disk->src, "attach", true);
 
 virDomainDiskInsertPreAlloced(vm->def, disk);
+ret = 0;
 
  cleanup:
 qemuDomainSecretDiskDestroy(disk);
@@ -407,6 +396,26 @@ qemuDomainAttachVirtioDiskDevice(virConnectPtr conn,
 virObjectUnref(cfg);
 return ret;
 
+ failadddevice:
+orig_err = virSaveLastError();
+if (!drivealias ||
+qemuMonitorDriveDel(priv->mon, drivealias) < 0) {
+VIR_WARN("Unable to remove drive %s (%s) after failed "
+ "qemuMonitorAddDevice",
+ NULLSTR(drivealias), drivestr);
+}
+if (orig_err) {
+virSetError(orig_err);
+virFreeError(orig_err);
+}
+
+ failadddrive:
+if (qemuDomainObjExitMonitor(driver, vm) < 0)
+releaseaddr = false;
+
+ failexitmonitor:
+virDomainAuditDisk(vm, NULL, disk->src, "attach", false);
+
  error:
 if (releaseaddr)
 qemuDomainReleaseDeviceAddress(vm, &disk->info, src);
-- 
2.5.5

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


[libvirt] [PATCH v2 12/12] qemu: Utilize qemu secret objects for SCSI/RBD auth/secret

2016-04-16 Thread John Ferlan
https://bugzilla.redhat.com/show_bug.cgi?id=1182074

If they're available and we need to pass secrets to qemu, then use the
qemu domain secret object in order to pass the secrets for iSCSI and
RBD volumes instead of passing plaintext or base64 encoded secrets on
the command line.

New APIs:

  qemuDomainGetIVKeyAlias:
Generate/return the secret object alias for an initialization
vector (IV) secret info type. This will be saved in the secret
info block.

  qemuDomainSecretInfoGetAlias:
Return a pointer to the alias to the specific secret info as
long as the secret object is supported (future patches may add
a new secret info type with a different pointer to return).

  qemuDomainSecretHaveEncrypt:
Boolean function to determine whether the underly encryption
API is available. This function will utilize a similar mechanism
as the 'gnutls_rnd' did in configure.ac. This function creates
the encrypted secret based upon the domain master key, an
initialization vector (16 byte random value), and the stored secret.

  qemuDomainSecretIVSetup: (private)
This API handles the details of the generation of the IV secret
and saves the pieces that need to be passed to qemu in order for
the secret to be decrypted. The requirement from qemu is the IV
and encrypted secret are to be base64 encoded. They can be passed
either directly or within a file. This implementation chooses
to pass directly rather than a file (file passing is shown below).

  qemuBuildiSCSICommandLine: (private)
  qemuBuildDiskiSCSICommandLine
  qemuBuildHostdeviSCSICommandLine
These API's will handle adding the IV secret onto an '-iscsi'
command line option.

  qemuBuildSecretInfoProps: (private)
Generate/return a JSON properties object for the IV secret to
be used by both the command building and eventually the hotplug
code in order to add the secret object.

Changes for qemuDomainSecret{Disk|Hostdev}Prepare:

  If both the encryption API exists and the secret object exist, then
  setup the IV secret (qemuDomainSecretIVSetup) as the default means
  for the disk/hostdev to provide the secret to qemu. Prior to command
  line generation and during hotplug, these prepare API's are called
  allowing for code after the API to perform the right steps.

Command Building:

  Adjust the qemuBuild{General|RBD}SecinfoURI API's in order to generate
  the specific command options for an IV secret, such as:

  For iSCSI:

-object secret,id=sec0,keyid=$masterKey,filename=/path/to/example.pw

   or

-object secret,id=sec0,keyid=$masterKey,data=$base64encodedencrypted,
format=base64

-iscsi -initiator-name=$iqn,user=user,password-secret=sec0
-drive file=iscsi://example.com/$iqn/1,...

  For RBD:

-object secret,id=secret0,keyid=$masterKey,file=/path/to/poolkey.b64,
format=base64

   or

-object secret,id=secret0,keyid=$masterKey,data=$base64encodedencrypted,
format=base64

-drive file=rbd:pool/image:id=myname:auth_supported=cephx\;none:\
   mon_host=mon1.example.org\:6321,password-secret=secret0,...

  where for both 'id=' value is the secret object alias, the 'keyid=
  $masterKey' is the master key shared with qemu, and the -drive
  syntax will reference that alias as the 'password-secret'. For
  the iSCSI object 'user=' replaces the URI generated 'user:secret@'
  prepended to the iSCSI 'host' name (example.com). For the RBD -drive
  syntax, the 'id=myname' is kept to define the username, while the
  'key=$base64 encoded secret' is removed.

  While according to the syntax described for qemu commits 'b189346eb'
  (iSCSI) and '60390a21' (RBD) or as seen in the email archive:

https://lists.gnu.org/archive/html/qemu-devel/2016-01/msg04083.html

  it is possible to pass a plaintext password via a file, the qemu
  commit 'ac1d8878' describes the more feature rich 'keyid=' option
  based upon the shared masterKey.

Tests:

  Add mock's for virRandomBytes and gnutls_rnd in order to return a
  constant stream of '0xff' in the bytes for a non random key in order
  to generate "constant" values for the secrets so that the tests can
  use those results to compare results.

Hotplug:

  Since the hotplug code doesn't add command line arguments, passing
  the encoded/plaintext secrets directly to the monitor will suffice.
  Besides, it's passing the IV secret via '-iscsi' won't be possible.
  Perhaps when the -drive command is modified to accept not only the
  initiator-name, but -user and -password-secret arguments, then the
  IV code can be utilized for hotplug secrets.

The goal is to make this the default and have no user interaction
required in order to allow using the IV mechanism. If the mechanism
is not available, then fall back to the current mechanism.

Signed-off-by: John Ferlan 
---
 configure.ac   |   1 +
 src/qemu/qemu_alias.c  |  23 ++

[libvirt] [PATCH v2 04/12] qemu: Introduce qemuDomainSecretHostdevPrepare and Destroy

2016-04-16 Thread John Ferlan
Similar to the qemuDomainSecretDiskPrepare, generate the secret
for the Hostdev's prior to call qemuProcessLaunch which calls
qemuBuildCommandLine. Additionally, since the secret is not longer
added as part of building the command, the hotplug code will need
to make the call to add the secret in the hostdevPriv.

Since this then is the last requirement to pass a virConnectPtr
to qemuBuildCommandLine, we now can remove that as part of these
changes. That removal has cascading effects through various callers.

Signed-off-by: John Ferlan 
---
 src/qemu/qemu_command.c | 41 +--
 src/qemu/qemu_command.h |  8 ++
 src/qemu/qemu_domain.c  | 73 +
 src/qemu/qemu_domain.h  |  7 +
 src/qemu/qemu_driver.c  |  3 +-
 src/qemu/qemu_hotplug.c | 31 +
 src/qemu/qemu_hotplug.h |  3 +-
 src/qemu/qemu_process.c |  5 ++--
 8 files changed, 120 insertions(+), 51 deletions(-)

diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 24ed8ed..9ecb7b6 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -50,7 +50,6 @@
 #include "secret_conf.h"
 #include "network/bridge_driver.h"
 #include "virnetdevtap.h"
-#include "secret_util.h"
 #include "device_conf.h"
 #include "virstoragefile.h"
 #include "virtpm.h"
@@ -4460,29 +4459,24 @@ qemuBuildSCSIHostHostdevDrvStr(virDomainHostdevDefPtr 
dev)
 }
 
 static char *
-qemuBuildSCSIiSCSIHostdevDrvStr(virConnectPtr conn,
-virDomainHostdevDefPtr dev)
+qemuBuildSCSIiSCSIHostdevDrvStr(virDomainHostdevDefPtr dev)
 {
 char *source = NULL;
 char *secret = NULL;
 char *username = NULL;
 virStorageSource src;
+qemuDomainHostdevPrivatePtr hostdevPriv = QEMU_DOMAIN_HOSTDEV_PRIVATE(dev);
 
 memset(&src, 0, sizeof(src));
 
 virDomainHostdevSubsysSCSIPtr scsisrc = &dev->source.subsys.u.scsi;
 virDomainHostdevSubsysSCSIiSCSIPtr iscsisrc = &scsisrc->u.iscsi;
 
-if (conn && iscsisrc->auth) {
-const char *protocol =
-virStorageNetProtocolTypeToString(VIR_STORAGE_NET_PROTOCOL_ISCSI);
-bool encode = false;
-int secretType = VIR_SECRET_USAGE_TYPE_ISCSI;
+if (hostdevPriv->secinfo) {
+qemuDomainSecretInfoPtr secinfo = hostdevPriv->secinfo;
 
-username = iscsisrc->auth->username;
-if (!(secret = virSecretGetSecretString(conn, protocol, encode,
-iscsisrc->auth, secretType)))
-goto cleanup;
+username = secinfo->s.plain.username;
+secret = secinfo->s.plain.secret;
 }
 
 src.protocol = VIR_STORAGE_NET_PROTOCOL_ISCSI;
@@ -4493,14 +4487,11 @@ qemuBuildSCSIiSCSIHostdevDrvStr(virConnectPtr conn,
 /* Rather than pull what we think we want - use the network disk code */
 source = qemuBuildNetworkDriveURI(&src, username, secret);
 
- cleanup:
-VIR_FREE(secret);
 return source;
 }
 
 char *
-qemuBuildSCSIHostdevDrvStr(virConnectPtr conn,
-   virDomainHostdevDefPtr dev,
+qemuBuildSCSIHostdevDrvStr(virDomainHostdevDefPtr dev,
virQEMUCapsPtr qemuCaps)
 {
 virBuffer buf = VIR_BUFFER_INITIALIZER;
@@ -4508,7 +4499,7 @@ qemuBuildSCSIHostdevDrvStr(virConnectPtr conn,
 virDomainHostdevSubsysSCSIPtr scsisrc = &dev->source.subsys.u.scsi;
 
 if (scsisrc->protocol == VIR_DOMAIN_HOSTDEV_SCSI_PROTOCOL_TYPE_ISCSI) {
-if (!(source = qemuBuildSCSIiSCSIHostdevDrvStr(conn, dev)))
+if (!(source = qemuBuildSCSIiSCSIHostdevDrvStr(dev)))
 goto error;
 virBufferAsprintf(&buf, "file=%s,if=none,format=raw", source);
 } else {
@@ -4806,7 +4797,6 @@ qemuBuildChrChardevStr(virLogManagerPtr logManager,
 
 static int
 qemuBuildHostdevCommandLine(virCommandPtr cmd,
-virConnectPtr conn,
 const virDomainDef *def,
 virQEMUCapsPtr qemuCaps,
 unsigned int *bootHostdevNet)
@@ -4955,8 +4945,7 @@ qemuBuildHostdevCommandLine(virCommandPtr cmd,
 char *drvstr;
 
 virCommandAddArg(cmd, "-drive");
-if (!(drvstr = qemuBuildSCSIHostdevDrvStr(conn, hostdev,
-  qemuCaps)))
+if (!(drvstr = qemuBuildSCSIHostdevDrvStr(hostdev, qemuCaps)))
 return -1;
 virCommandAddArg(cmd, drvstr);
 VIR_FREE(drvstr);
@@ -9193,13 +9182,9 @@ qemuBuildCommandLineValidate(virQEMUDriverPtr driver,
 /*
  * Constructs a argv suitable for launching qemu with config defined
  * for a given virtual machine.
- *
- * XXX 'conn' is only required to resolve network -> bridge name
- * figure out how to remove this requirement some day
  */
 virCommandPtr
-qemuBuildCommandLine(virConnectPtr conn,
- virQEMUDriverPtr driver,
+qemuBuildCommandLine(virQEMUDriverPt

[libvirt] [PATCH v2 05/12] qemu: Use qemuDomainSecretInfoPtr in qemuBuildNetworkDriveURI

2016-04-16 Thread John Ferlan
Rather than take username and password as parameters, now take
a qemuDomainSecretInfoPtr and decode within the function.

NB: Having secinfo implies having the username for a plain type
from a successful virSecretGetSecretString

Signed-off-by: John Ferlan 
---
 src/qemu/qemu_command.c | 40 +---
 1 file changed, 13 insertions(+), 27 deletions(-)

diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 9ecb7b6..8629c15 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -610,8 +610,7 @@ qemuNetworkDriveGetPort(int protocol,
 
 static char *
 qemuBuildNetworkDriveURI(virStorageSourcePtr src,
- const char *username,
- const char *secret)
+ qemuDomainSecretInfoPtr secinfo)
 {
 char *ret = NULL;
 virBuffer buf = VIR_BUFFER_INITIALIZER;
@@ -722,12 +721,14 @@ qemuBuildNetworkDriveURI(virStorageSourcePtr src,
 virAsprintf(&uri->query, "socket=%s", src->hosts->socket) < 0)
 goto cleanup;
 
-if (username) {
-if (secret) {
-if (virAsprintf(&uri->user, "%s:%s", username, secret) < 0)
+if (secinfo) {
+if (secinfo->s.plain.secret) {
+if (virAsprintf(&uri->user, "%s:%s",
+secinfo->s.plain.username,
+secinfo->s.plain.secret) < 0)
 goto cleanup;
 } else {
-if (VIR_STRDUP(uri->user, username) < 0)
+if (VIR_STRDUP(uri->user, secinfo->s.plain.username) < 0)
 goto cleanup;
 }
 }
@@ -776,11 +777,12 @@ qemuBuildNetworkDriveURI(virStorageSourcePtr src,
 if (src->snapshot)
 virBufferEscape(&buf, '\\', ":", "@%s", src->snapshot);
 
-if (username) {
-virBufferEscape(&buf, '\\', ":", ":id=%s", username);
+if (secinfo) {
+virBufferEscape(&buf, '\\', ":", ":id=%s",
+secinfo->s.plain.username);
 virBufferEscape(&buf, '\\', ":",
 ":key=%s:auth_supported=cephx\\;none",
-secret);
+secinfo->s.plain.secret);
 } else {
 virBufferAddLit(&buf, ":auth_supported=none");
 }
@@ -835,8 +837,6 @@ qemuGetDriveSourceString(virStorageSourcePtr src,
  char **source)
 {
 int actualType = virStorageSourceGetActualType(src);
-char *secret = NULL;
-char *username = NULL;
 int ret = -1;
 
 *source = NULL;
@@ -855,12 +855,7 @@ qemuGetDriveSourceString(virStorageSourcePtr src,
 break;
 
 case VIR_STORAGE_TYPE_NETWORK:
-if (secinfo) {
-username = secinfo->s.plain.username;
-secret = secinfo->s.plain.secret;
-}
-
-if (!(*source = qemuBuildNetworkDriveURI(src, username, secret)))
+if (!(*source = qemuBuildNetworkDriveURI(src, secinfo)))
 goto cleanup;
 break;
 
@@ -4462,8 +4457,6 @@ static char *
 qemuBuildSCSIiSCSIHostdevDrvStr(virDomainHostdevDefPtr dev)
 {
 char *source = NULL;
-char *secret = NULL;
-char *username = NULL;
 virStorageSource src;
 qemuDomainHostdevPrivatePtr hostdevPriv = QEMU_DOMAIN_HOSTDEV_PRIVATE(dev);
 
@@ -4472,20 +4465,13 @@ qemuBuildSCSIiSCSIHostdevDrvStr(virDomainHostdevDefPtr 
dev)
 virDomainHostdevSubsysSCSIPtr scsisrc = &dev->source.subsys.u.scsi;
 virDomainHostdevSubsysSCSIiSCSIPtr iscsisrc = &scsisrc->u.iscsi;
 
-if (hostdevPriv->secinfo) {
-qemuDomainSecretInfoPtr secinfo = hostdevPriv->secinfo;
-
-username = secinfo->s.plain.username;
-secret = secinfo->s.plain.secret;
-}
-
 src.protocol = VIR_STORAGE_NET_PROTOCOL_ISCSI;
 src.path = iscsisrc->path;
 src.hosts = iscsisrc->hosts;
 src.nhosts = iscsisrc->nhosts;
 
 /* Rather than pull what we think we want - use the network disk code */
-source = qemuBuildNetworkDriveURI(&src, username, secret);
+source = qemuBuildNetworkDriveURI(&src, hostdevPriv->secinfo);
 
 return source;
 }
-- 
2.5.5

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


[libvirt] [PATCH v2 09/12] qemu: hotplug: Adjust error path for attach hostdev scsi disk

2016-04-16 Thread John Ferlan
Adjust error path logic to make it clearer how to undo the failed add.

Signed-off-by: John Ferlan 
---
 src/qemu/qemu_hotplug.c | 52 ++---
 1 file changed, 32 insertions(+), 20 deletions(-)

diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 17a70a3..c206369 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -1925,6 +1925,7 @@ qemuDomainAttachHostSCSIDevice(virConnectPtr conn,
 {
 int ret = -1;
 qemuDomainObjPrivatePtr priv = vm->privateData;
+virErrorPtr orig_err;
 virDomainControllerDefPtr cont = NULL;
 char *devstr = NULL;
 char *drvstr = NULL;
@@ -1984,32 +1985,24 @@ qemuDomainAttachHostSCSIDevice(virConnectPtr conn,
 if (VIR_REALLOC_N(vm->def->hostdevs, vm->def->nhostdevs + 1) < 0)
 goto cleanup;
 
+/* Attach the device - 2 step process */
 qemuDomainObjEnterMonitor(driver, vm);
-if ((ret = qemuMonitorAddDrive(priv->mon, drvstr)) == 0) {
-if ((ret = qemuMonitorAddDevice(priv->mon, devstr)) < 0) {
-virErrorPtr orig_err = virSaveLastError();
-if (qemuMonitorDriveDel(priv->mon, drvstr) < 0)
-VIR_WARN("Unable to remove drive %s (%s) after failed "
- "qemuMonitorAddDevice",
- drvstr, devstr);
-if (orig_err) {
-virSetError(orig_err);
-virFreeError(orig_err);
-}
-}
-}
-if (qemuDomainObjExitMonitor(driver, vm) < 0) {
-ret = -1;
-goto cleanup;
-}
 
-virDomainAuditHostdev(vm, hostdev, "attach", ret == 0);
-if (ret < 0)
-goto cleanup;
+if (qemuMonitorAddDrive(priv->mon, drvstr) < 0)
+goto failadddrive;
+
+if (qemuMonitorAddDevice(priv->mon, devstr) < 0)
+goto failadddevice;
+
+if (qemuDomainObjExitMonitor(driver, vm) < 0)
+goto failexitmonitor;
+
+virDomainAuditHostdev(vm, hostdev, "attach", true);
 
 vm->def->hostdevs[vm->def->nhostdevs++] = hostdev;
 
 ret = 0;
+
  cleanup:
 qemuDomainSecretHostdevDestroy(hostdev);
 if (ret < 0) {
@@ -2024,6 +2017,25 @@ qemuDomainAttachHostSCSIDevice(virConnectPtr conn,
 VIR_FREE(drvstr);
 VIR_FREE(devstr);
 return ret;
+
+ failadddevice:
+orig_err = virSaveLastError();
+if (qemuMonitorDriveDel(priv->mon, drvstr) < 0)
+VIR_WARN("Unable to remove drive %s (%s) after failed "
+ "qemuMonitorAddDevice",
+ drvstr, devstr);
+if (orig_err) {
+virSetError(orig_err);
+virFreeError(orig_err);
+}
+
+ failadddrive:
+ignore_value(qemuDomainObjExitMonitor(driver, vm));
+
+ failexitmonitor:
+virDomainAuditHostdev(vm, hostdev, "attach", false);
+
+goto cleanup;
 }
 
 
-- 
2.5.5

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


[libvirt] [PATCH v2 07/12] qemu: hotplug: Adjust error path for attach scsi disk

2016-04-16 Thread John Ferlan
Adjust error path logic to make it clearer how to undo the failed add.

Signed-off-by: John Ferlan 
---
 src/qemu/qemu_hotplug.c | 35 +++
 1 file changed, 19 insertions(+), 16 deletions(-)

diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 11efd7b..ae314be 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -584,29 +584,22 @@ qemuDomainAttachSCSIDisk(virConnectPtr conn,
 if (VIR_REALLOC_N(vm->def->disks, vm->def->ndisks+1) < 0)
 goto error;
 
+/* Attach the device - 2 step process */
 qemuDomainObjEnterMonitor(driver, vm);
 
-ret = qemuMonitorAddDrive(priv->mon, drivestr);
-if (ret == 0) {
-ret = qemuMonitorAddDevice(priv->mon, devstr);
-if (ret < 0) {
-VIR_WARN("qemuMonitorAddDevice failed on %s (%s)",
- drivestr, devstr);
-/* XXX should call 'drive_del' on error but this does not exist 
yet */
-}
-}
+if (qemuMonitorAddDrive(priv->mon, drivestr) < 0)
+goto failadddrive;
 
-if (qemuDomainObjExitMonitor(driver, vm) < 0) {
-ret = -1;
-goto error;
-}
+if (qemuMonitorAddDevice(priv->mon, devstr) < 0)
+goto failadddevice;
 
-virDomainAuditDisk(vm, NULL, disk->src, "attach", ret >= 0);
+if (qemuDomainObjExitMonitor(driver, vm) < 0)
+goto failexitmonitor;
 
-if (ret < 0)
-goto error;
+virDomainAuditDisk(vm, NULL, disk->src, "attach", true);
 
 virDomainDiskInsertPreAlloced(vm->def, disk);
+ret = 0;
 
  cleanup:
 qemuDomainSecretDiskDestroy(disk);
@@ -615,6 +608,16 @@ qemuDomainAttachSCSIDisk(virConnectPtr conn,
 virObjectUnref(cfg);
 return ret;
 
+ failadddevice:
+/* XXX should call 'drive_del' on error but this does not exist yet */
+VIR_WARN("qemuMonitorAddDevice failed on %s (%s)", drivestr, devstr);
+
+ failadddrive:
+ignore_value(qemuDomainObjExitMonitor(driver, vm));
+
+ failexitmonitor:
+virDomainAuditDisk(vm, NULL, disk->src, "attach", false);
+
  error:
 ignore_value(qemuDomainPrepareDisk(driver, vm, disk, NULL, true));
 goto cleanup;
-- 
2.5.5

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


[libvirt] [PATCH v2 02/12] qemu: Introduce qemuDomainSecretPrepare and Destroy

2016-04-16 Thread John Ferlan
Rather than needing to pass the conn parameter to various command
line building API's, add qemuDomainSecretPrepare just prior to the
qemuProcessLaunch which calls qemuBuilCommandLine. The function
must be called after qemuProcessPrepareHost since it's expected
to eventually need the domain masterKey generated during the prepare
host call. Additionally, future patches may require device aliases
(assigned during the prepare domain call) in order to associate
the secret objects.

The qemuDomainSecretDestroy is called after the qemuProcessLaunch
finishes in order to clear and free memory used by the secrets
that were recently prepared, so they are not kept around in memory
too long.

Placing the setup here is beneficial for future patches which will
need the domain masterKey in order to generate an encrypted secret
along with an initialization vector to be saved and passed (since
the masterKey shouldn't be passed around).

Finally, since the secret is not added during command line build,
the hotplug code will need to get the secret into the private disk data.

Signed-off-by: John Ferlan 
---
 src/qemu/qemu_command.c |  45 ---
 src/qemu/qemu_command.h |   5 +-
 src/qemu/qemu_domain.c  | 150 ++--
 src/qemu/qemu_domain.h  |  15 -
 src/qemu/qemu_driver.c  |  10 ++--
 src/qemu/qemu_hotplug.c |  26 +
 src/qemu/qemu_hotplug.h |   1 -
 src/qemu/qemu_process.c |   8 +++
 8 files changed, 202 insertions(+), 58 deletions(-)

diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 26c19ff..24ed8ed 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -832,7 +832,7 @@ qemuBuildNetworkDriveURI(virStorageSourcePtr src,
 
 int
 qemuGetDriveSourceString(virStorageSourcePtr src,
- virConnectPtr conn,
+ qemuDomainSecretInfoPtr secinfo,
  char **source)
 {
 int actualType = virStorageSourceGetActualType(src);
@@ -846,31 +846,6 @@ qemuGetDriveSourceString(virStorageSourcePtr src,
 if (virStorageSourceIsEmpty(src))
 return 1;
 
-if (conn) {
-if (actualType == VIR_STORAGE_TYPE_NETWORK &&
-src->auth &&
-(src->protocol == VIR_STORAGE_NET_PROTOCOL_ISCSI ||
- src->protocol == VIR_STORAGE_NET_PROTOCOL_RBD)) {
-bool encode = false;
-int secretType = VIR_SECRET_USAGE_TYPE_ISCSI;
-const char *protocol = 
virStorageNetProtocolTypeToString(src->protocol);
-username = src->auth->username;
-
-if (src->protocol == VIR_STORAGE_NET_PROTOCOL_RBD) {
-/* qemu requires the secret to be encoded for RBD */
-encode = true;
-secretType = VIR_SECRET_USAGE_TYPE_CEPH;
-}
-
-if (!(secret = virSecretGetSecretString(conn,
-protocol,
-encode,
-src->auth,
-secretType)))
-goto cleanup;
-}
-}
-
 switch ((virStorageType) actualType) {
 case VIR_STORAGE_TYPE_BLOCK:
 case VIR_STORAGE_TYPE_FILE:
@@ -881,6 +856,11 @@ qemuGetDriveSourceString(virStorageSourcePtr src,
 break;
 
 case VIR_STORAGE_TYPE_NETWORK:
+if (secinfo) {
+username = secinfo->s.plain.username;
+secret = secinfo->s.plain.secret;
+}
+
 if (!(*source = qemuBuildNetworkDriveURI(src, username, secret)))
 goto cleanup;
 break;
@@ -894,7 +874,6 @@ qemuGetDriveSourceString(virStorageSourcePtr src,
 ret = 0;
 
  cleanup:
-VIR_FREE(secret);
 return ret;
 }
 
@@ -1033,8 +1012,7 @@ qemuCheckFips(void)
 
 
 char *
-qemuBuildDriveStr(virConnectPtr conn,
-  virDomainDiskDefPtr disk,
+qemuBuildDriveStr(virDomainDiskDefPtr disk,
   bool bootable,
   virQEMUCapsPtr qemuCaps)
 {
@@ -1046,6 +1024,7 @@ qemuBuildDriveStr(virConnectPtr conn,
 int busid = -1, unitid = -1;
 char *source = NULL;
 int actualType = virStorageSourceGetActualType(disk->src);
+qemuDomainDiskPrivatePtr diskPriv = QEMU_DOMAIN_DISK_PRIVATE(disk);
 
 if (idx < 0) {
 virReportError(VIR_ERR_INTERNAL_ERROR,
@@ -1127,7 +1106,7 @@ qemuBuildDriveStr(virConnectPtr conn,
 break;
 }
 
-if (qemuGetDriveSourceString(disk->src, conn, &source) < 0)
+if (qemuGetDriveSourceString(disk->src, diskPriv->secinfo, &source) < 0)
 goto error;
 
 if (source &&
@@ -1816,7 +1795,6 @@ qemuBuildDriveDevStr(const virDomainDef *def,
 
 static int
 qemuBuildDiskDriveCommandLine(virCommandPtr cmd,
-  virConnectPtr conn,
   const virDomainDef *def,
   virQEMUCapsPtr qemuCaps,
 

[libvirt] [PATCH v2 10/12] qemu: hotplug: Fix possible memory leak of props

2016-04-16 Thread John Ferlan
If we failed to build the aliases or attach the chardev, then the props
would be leaked - fix that.

Signed-off-by: John Ferlan 
---
 src/qemu/qemu_hotplug.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index c206369..c05f88c 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -1686,6 +1686,7 @@ qemuDomainAttachRNGDevice(virQEMUDriverPtr driver,
 
 if (qemuMonitorAddObject(priv->mon, type, objAlias, props) < 0)
 goto failbackend;
+props = NULL;
 
 if (qemuMonitorAddDevice(priv->mon, devstr) < 0)
 goto failfrontend;
@@ -1703,6 +1704,7 @@ qemuDomainAttachRNGDevice(virQEMUDriverPtr driver,
  audit:
 virDomainAuditRNG(vm, NULL, rng, "attach", ret == 0);
  cleanup:
+virJSONValueFree(props);
 if (ret < 0 && vm)
 qemuDomainReleaseDeviceAddress(vm, &rng->info, NULL);
 VIR_FREE(charAlias);
@@ -1716,6 +1718,7 @@ qemuDomainAttachRNGDevice(virQEMUDriverPtr driver,
  failbackend:
 if (rng->backend == VIR_DOMAIN_RNG_BACKEND_EGD)
 ignore_value(qemuMonitorDetachCharDev(priv->mon, charAlias));
+props = NULL;  /* qemuMonitorAddObject consumes on failure */
  failchardev:
 if (qemuDomainObjExitMonitor(driver, vm) < 0) {
 vm = NULL;
-- 
2.5.5

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


[libvirt] [PATCH v2 01/12] qemu: Introduce qemuDomainSecretInfo

2016-04-16 Thread John Ferlan
Introduce a new private structure to hold qemu domain auth/secret data.
This will be stored in the qemuDomainDiskPrivate as a means to store the
auth and fetched secret data rather than generating during building of
the command line.

The initial changes will handle the current username and secret values
for rbd and iscsi disks (in their various forms). The rbd secret is
stored as a base64 encoded value, while the iscsi secret is stored as
a plain text value. Future changes will store encoded/encrypted secret
data as well as an initialization vector needed to be given to qemu
in order to decrypt the encoded password along with the domain masterKey.
The inital assumption will be that VIR_DOMAIN_SECRET_INFO_PLAIN is
being used.

Although it's expected that the cleanup of the secret data will be
done immediately after command line generation, reintroduce the object
dispose function qemuDomainDiskPrivateDispose to handle removing
memory associated with the structure for "normal" cleanup paths.

Signed-off-by: John Ferlan 
---
 src/qemu/qemu_domain.c | 32 +++-
 src/qemu/qemu_domain.h | 27 +++
 2 files changed, 58 insertions(+), 1 deletion(-)

diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index ed1e0e5..55cb30f 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -729,7 +729,28 @@ qemuDomainMasterKeyCreate(virQEMUDriverPtr driver,
 }
 
 
+static void
+qemuDomainSecretPlainFree(qemuDomainSecretPlain secret)
+{
+VIR_FREE(secret.username);
+memset(secret.secret, 0, strlen(secret.secret));
+VIR_FREE(secret.secret);
+}
+
+
+static void
+qemuDomainSecretInfoFree(qemuDomainSecretInfoPtr *secinfo)
+{
+if (!*secinfo)
+return;
+
+qemuDomainSecretPlainFree((*secinfo)->s.plain);
+VIR_FREE(*secinfo);
+}
+
+
 static virClassPtr qemuDomainDiskPrivateClass;
+static void qemuDomainDiskPrivateDispose(void *obj);
 
 static int
 qemuDomainDiskPrivateOnceInit(void)
@@ -737,7 +758,7 @@ qemuDomainDiskPrivateOnceInit(void)
 qemuDomainDiskPrivateClass = virClassNew(virClassForObject(),
  "qemuDomainDiskPrivate",
  sizeof(qemuDomainDiskPrivate),
- NULL);
+ qemuDomainDiskPrivateDispose);
 if (!qemuDomainDiskPrivateClass)
 return -1;
 else
@@ -761,6 +782,15 @@ qemuDomainDiskPrivateNew(void)
 }
 
 
+static void
+qemuDomainDiskPrivateDispose(void *obj)
+{
+qemuDomainDiskPrivatePtr priv = obj;
+
+qemuDomainSecretInfoFree(&priv->secinfo);
+}
+
+
 /* This is the old way of setting up per-domain directories */
 static int
 qemuDomainSetPrivatePathsOld(virQEMUDriverPtr driver,
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index 7d2c4fd..9cfe3e4 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -239,6 +239,29 @@ struct _qemuDomainObjPrivate {
 size_t masterKeyLen;
 };
 
+/* Type of domain secret */
+typedef enum {
+VIR_DOMAIN_SECRET_INFO_PLAIN = 0,
+
+VIR_DOMAIN_SECRET_INFO_LAST
+} qemuDomainSecretInfoType;
+
+typedef struct _qemuDomainSecretPlain qemuDomainSecretPlain;
+typedef struct _qemuDomainSecretPlain *qemuDomainSecretPlainPtr;
+struct _qemuDomainSecretPlain {
+char *username;
+char *secret;
+};
+
+typedef struct _qemuDomainSecretInfo qemuDomainSecretInfo;
+typedef qemuDomainSecretInfo *qemuDomainSecretInfoPtr;
+struct _qemuDomainSecretInfo {
+int type;  /* qemuDomainSecretInfoType */
+union {
+qemuDomainSecretPlain plain;
+} s;
+};
+
 # define QEMU_DOMAIN_DISK_PRIVATE(disk)\
 ((qemuDomainDiskPrivatePtr) (disk)->privateData)
 
@@ -258,6 +281,10 @@ struct _qemuDomainDiskPrivate {
 bool blockJobSync; /* the block job needs synchronized termination */
 
 bool migrating; /* the disk is being migrated */
+
+/* for storage devices using auth/secret
+ * NB: *not* to be written to qemu domain object XML */
+qemuDomainSecretInfoPtr secinfo;
 };
 
 typedef enum {
-- 
2.5.5

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


[libvirt] [PATCH v2 00/12] Add IV Secret Object support

2016-04-16 Thread John Ferlan
v1: http://www.redhat.com/archives/libvir-list/2016-April/msg00596.html

Differences since v1:

 - Add qemuBuildiSCSICommandLine (and BuildDiskiSCSI && BuildHostdeviSCSI)
   These will do the magic necessary in order to support IV secret objects
   for the impending iSCSI -drive argument. This API doesn't require any
   qemu patches in order to work AFAICT. I also determined that the "id="
   *isn't* required for an '-iscsi ...' argument, which made using the
   complete 'path' string for 'initiator-name' possible. The other option
   was to break it up and pass the "iqn.*" string as the initiator-name
   and a "modified" remaining string as the "id=" parameter. The modified
   would be to ensure only alphanumeric, '-', '.', and '_' characters are
   in the 'id=' string.

 - Fix up some logic found while actually working through the tests. Some
   of it related to what was found for the 'iscsi' options.  A couple of
   other minor nits.

 - Add tests and mocks for virRandomBytes and gnutls_rnd (note: the former
   could be used to "randomly" (hah!) generate a UUID of all '0xff').
   A mock of 'gnutls_encrypt' is not necessary since, it can only be called
   if the function gnutls_encrypt exists *and* we have a secret object
   capability.  Not having a mock function allows us to validate that
   gnutls_encrypt actually generates a value we expect based on some
   less than stellar and totally non random key's!

 - Remove the hotplug IV code (I've saved it off for future expansion).
   Although not needing to do hotplug probably means patches 6-9 are not
   required, but still I think better than the existing so I kept them
   even though they have nothing to do with IV secrets (they'd need to
   go in after patches 1-5 anyways).

 - Ran the changes through the coverity checker...

John Ferlan (12):
  qemu: Introduce qemuDomainSecretInfo
  qemu: Introduce qemuDomainSecretPrepare and Destroy
  qemu: Introduce qemuDomainHostdevPrivatePtr
  qemu: Introduce qemuDomainSecretHostdevPrepare and Destroy
  qemu: Use qemuDomainSecretInfoPtr in qemuBuildNetworkDriveURI
  qemu: hotplug: Assume support for -device for attach virtio disk
  qemu: hotplug: Adjust error path for attach scsi disk
  qemu: hotplug: Adjust error path for attach virtio disk
  qemu: hotplug: Adjust error path for attach hostdev scsi disk
  qemu: hotplug: Fix possible memory leak of props
  qemu: Introduce qemuDomainSecretIV
  qemu: Utilize qemu secret objects for SCSI/RBD auth/secret

 configure.ac   |   1 +
 src/conf/domain_conf.c |  33 +-
 src/conf/domain_conf.h |   5 +-
 src/lxc/lxc_native.c   |   4 +-
 src/qemu/qemu_alias.c  |  23 +
 src/qemu/qemu_alias.h  |   2 +
 src/qemu/qemu_command.c| 445 ++
 src/qemu/qemu_command.h|  13 +-
 src/qemu/qemu_domain.c | 516 -
 src/qemu/qemu_domain.h |  81 +++-
 src/qemu/qemu_driver.c |  13 +-
 src/qemu/qemu_hotplug.c| 247 +-
 src/qemu/qemu_hotplug.h|   4 +-
 src/qemu/qemu_parse_command.c  |   4 +-
 src/qemu/qemu_process.c|  13 +-
 src/vbox/vbox_common.c |   4 +-
 src/xenconfig/xen_common.c |   4 +-
 src/xenconfig/xen_sxpr.c   |   4 +-
 ...uxml2argv-disk-drive-network-iscsi-auth-IV.args |  39 ++
 ...muxml2argv-disk-drive-network-iscsi-auth-IV.xml |  43 ++
 ...emuxml2argv-disk-drive-network-rbd-auth-IV.args |  31 ++
 ...qemuxml2argv-disk-drive-network-rbd-auth-IV.xml |  42 ++
 ...emuxml2argv-hostdev-scsi-lsi-iscsi-auth-IV.args |  41 ++
 ...qemuxml2argv-hostdev-scsi-lsi-iscsi-auth-IV.xml |  48 ++
 ...xml2argv-hostdev-scsi-virtio-iscsi-auth-IV.args |  43 ++
 ...uxml2argv-hostdev-scsi-virtio-iscsi-auth-IV.xml |  48 ++
 tests/qemuxml2argvmock.c   |  31 +-
 tests/qemuxml2argvtest.c   |  19 +
 tests/virhostdevtest.c |   3 +-
 29 files changed, 1557 insertions(+), 247 deletions(-)
 create mode 100644 
tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-iscsi-auth-IV.args
 create mode 100644 
tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-iscsi-auth-IV.xml
 create mode 100644 
tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-rbd-auth-IV.args
 create mode 100644 
tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-rbd-auth-IV.xml
 create mode 100644 
tests/qemuxml2argvdata/qemuxml2argv-hostdev-scsi-lsi-iscsi-auth-IV.args
 create mode 100644 
tests/qemuxml2argvdata/qemuxml2argv-hostdev-scsi-lsi-iscsi-auth-IV.xml
 create mode 100644 
tests/qemuxml2argvdata/qemuxml2argv-hostdev-scsi-virtio-iscsi-au

Re: [libvirt] [PATCH] qemu: reject min_guarantee at parse time

2016-04-16 Thread Martin Kletzander

On Fri, Apr 15, 2016 at 05:37:17PM -0400, Cole Robinson wrote:

min_guarantee isn't implemented for qemu, and an explicit check was
added in june 2014 to reject the VM at qemu startup time. It's a weird
place to do XML validation, so move it to the post parse area where
we have similar checks.



NACK, it's done precisely there because if there is any domain that has
that parameter already in, it will disappear after upgrade to libvirt
with this patch.  That's what we have that validation function for and
the reason why it is called when the domain is being started.

We have bunch of similar issues that I wanted to address globally, but
it doesn't look like it will work in near future.


Also drop a validation check against min_guarantee in the command line
building; it will never see min_guarantee there.
---
src/qemu/qemu_command.c | 1 -
src/qemu/qemu_domain.c  | 7 +++
src/qemu/qemu_process.c | 7 ---
3 files changed, 7 insertions(+), 8 deletions(-)

diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 26c19ff..2fb967a 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -9143,7 +9143,6 @@ qemuBuildCommandLineValidate(virQEMUDriverPtr driver,

if (virMemoryLimitIsSet(def->mem.hard_limit) ||
virMemoryLimitIsSet(def->mem.soft_limit) ||
-def->mem.min_guarantee ||
virMemoryLimitIsSet(def->mem.swap_hard_limit)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
   _("Memory tuning is not available in session mode"));
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 73187ce..f5fafc8 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -1690,6 +1690,13 @@ qemuDomainDefPostParse(virDomainDefPtr def,
return ret;
}

+if (def->mem.min_guarantee) {
+virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+   _("Parameter 'min_guarantee' "
+ "not supported by QEMU."));
+return -1;
+}
+
if (def->os.loader &&
def->os.loader->type == VIR_DOMAIN_LOADER_TYPE_PFLASH &&
def->os.loader->readonly == VIR_TRISTATE_SWITCH_ON &&
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 81d86c2..387aff5 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -4550,13 +4550,6 @@ qemuProcessStartValidate(virQEMUDriverPtr driver,
virDomainDefCheckDuplicateDiskInfo(vm->def) < 0)
return -1;

-if (vm->def->mem.min_guarantee) {
-virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-   _("Parameter 'min_guarantee' "
- "not supported by QEMU."));
-return -1;
-}
-
VIR_DEBUG("Checking for any possible (non-fatal) issues");

/*
--
2.7.3

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


signature.asc
Description: Digital signature
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

[libvirt] [PATCH] tests: Fix syntax in iSCSI auth/secret tests

2016-04-16 Thread John Ferlan
While working on the tests for the secret initialization vector, I found
that the existing iSCSI tests were lacking in how they defined the IQN.
Many had IQN's of just 'iqn.1992-01.com.example' for one disk while using
'iqn.1992-01.com.example/1' for the second disk (same for hostdevs - guess
how they were copied/generated).

Typically (and documented this way), IQN's would include be of the form
'iqn.1992-01.com.example:storage/1' indicating an IQN using "storage" for
naming authority specific string and "/1" for the iSCSI LUN.

So modify the input XML's to use the more proper format - this of course
has a ripple effect on the output XML and the args.

Also note that the "%3A" is generated by the virURIFormat/xmlSaveUri
to represent the colon.

Signed-off-by: John Ferlan 
---
 .../qemuargv2xml-disk-drive-network-iscsi-auth.args   | 6 +++---
 .../qemuargv2xml-disk-drive-network-iscsi-auth.xml| 4 ++--
 .../qemuxml2argv-disk-drive-network-iscsi-auth.args   | 8 +---
 .../qemuxml2argv-disk-drive-network-iscsi-auth.xml| 7 +--
 .../qemuxml2argv-hostdev-scsi-lsi-iscsi-auth.args | 4 ++--
 .../qemuxml2argvdata/qemuxml2argv-hostdev-scsi-lsi-iscsi-auth.xml | 4 ++--
 .../qemuxml2argv-hostdev-scsi-virtio-iscsi-auth.args  | 4 ++--
 .../qemuxml2argv-hostdev-scsi-virtio-iscsi-auth.xml   | 4 ++--
 .../qemuxml2xmlout-disk-drive-network-iscsi-auth.xml  | 7 +--
 .../qemuxml2xmlout-hostdev-scsi-lsi-iscsi-auth.xml| 4 ++--
 .../qemuxml2xmlout-hostdev-scsi-virtio-iscsi-auth.xml | 4 ++--
 11 files changed, 32 insertions(+), 24 deletions(-)

diff --git 
a/tests/qemuargv2xmldata/qemuargv2xml-disk-drive-network-iscsi-auth.args 
b/tests/qemuargv2xmldata/qemuargv2xml-disk-drive-network-iscsi-auth.args
index 5bebcae..44c9506 100644
--- a/tests/qemuargv2xmldata/qemuargv2xml-disk-drive-network-iscsi-auth.args
+++ b/tests/qemuargv2xmldata/qemuargv2xml-disk-drive-network-iscsi-auth.args
@@ -17,9 +17,9 @@ QEMU_AUDIO_DRV=none \
 -boot c \
 -usb \
 -drive file=iscsi://myname:aqcvn5ho6hzfahaaq0ncv8jtjcice+hoblm...@example.org:\
-6000/iqn.1992-01.com.example,format=raw,if=virtio \
--drive file=iscsi://example.org:6000/iqn.1992-01.com.example/1,format=raw,\
-if=virtio \
+6000/iqn.1992-01.com.example%3Astorage/1,format=raw,if=virtio \
+-drive file=iscsi://example.org:6000/iqn.1992-01.com.example%3Astorage/2,\
+format=raw,if=virtio \
 -net none \
 -serial none \
 -parallel none
diff --git 
a/tests/qemuargv2xmldata/qemuargv2xml-disk-drive-network-iscsi-auth.xml 
b/tests/qemuargv2xmldata/qemuargv2xml-disk-drive-network-iscsi-auth.xml
index 35b3abc..b5f948b 100644
--- a/tests/qemuargv2xmldata/qemuargv2xml-disk-drive-network-iscsi-auth.xml
+++ b/tests/qemuargv2xmldata/qemuargv2xml-disk-drive-network-iscsi-auth.xml
@@ -19,14 +19,14 @@
   
 
   
-  
+  
 
   
   
 
 
   
-  
+  
 
   
   
diff --git 
a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-iscsi-auth.args 
b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-iscsi-auth.args
index 735a0ae..66e2497 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-iscsi-auth.args
+++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-iscsi-auth.args
@@ -18,10 +18,12 @@ QEMU_AUDIO_DRV=none \
 -boot c \
 -usb \
 -drive file=iscsi://myname:aqcvn5ho6hzfahaaq0ncv8jtjcice+hoblm...@example.org:\
-6000/iqn.1992-01.com.example,format=raw,if=none,id=drive-virtio-disk0 \
+6000/iqn.1992-01.com.example%3Astorage/1,format=raw,if=none,\
+id=drive-virtio-disk0 \
 -device virtio-blk-pci,bus=pci.0,addr=0x3,drive=drive-virtio-disk0,\
 id=virtio-disk0 \
--drive file=iscsi://example.org:6000/iqn.1992-01.com.example/1,format=raw,\
-if=none,id=drive-virtio-disk1 \
+-drive file=iscsi://myname:aqcvn5ho6hzfahaaq0ncv8jtjcice+hoblm...@example.org:\
+6000/iqn.1992-01.com.example%3Astorage/2,format=raw,if=none,\
+id=drive-virtio-disk1 \
 -device virtio-blk-pci,bus=pci.0,addr=0x4,drive=drive-virtio-disk1,\
 id=virtio-disk1
diff --git 
a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-iscsi-auth.xml 
b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-iscsi-auth.xml
index 5ac4abf..1f80d3b 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-iscsi-auth.xml
+++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-iscsi-auth.xml
@@ -19,14 +19,17 @@
   
 
   
-  
+  
 
   
   
 
 
   
-  
+  
+
+  
+  
 
   
   
diff --git 
a/tests/qemuxml2argvdata/qemuxml2argv-hostdev-scsi-lsi-iscsi-auth.args 
b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-scsi-lsi-iscsi-auth.args
index 2bd98e5..ff6655f 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-hostdev-scsi-lsi-iscsi-auth.args
+++ b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-scsi-lsi-iscsi-auth.args
@@ -21,9 +21,9 @@ QEMU_AUDIO_DRV=

Re: [libvirt] RFC: virtio-rng and /dev/urandom

2016-04-16 Thread Paolo Bonzini
> Also, I do not believe /dev/urandom is FIPS compliant.  Finally, the refill
> policy is different, so it is not really true the algorithm is the same.
> 
> All in all, other than a seed value it really doesn't make any sense.  Of
> course, none of this matters on newer Intel hardware ;)

Right, but there's always the point about people that use heterogeneous
hosts and cannot pass rdrand/rdseed to the guest.  For these, we should
add a QEMU driver that uses rdrand/rdseed, and thus decouples virtio-rng
from the host /dev/* completely.

>From the libvirt POV there are various possibilities:

- Libvirt can have a libvirt.conf parameter that says "ignore whatever is
specified in the guest XML if rdrand/rdseed is available, and instead use
rdrand/rdseed".

- Libvirt can allow specifying rdrand/rdseed _and_ an additional backend,
like this:


/dev/random

and fallback to the second if rdrand/rdseed are not available.

Paolo

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