[libvirt] [PATCH v9 4/5] qemu: Add a secret object to/for a chardev tcp with secret

Pavel Hrdina phrdina at redhat.com
Mon Oct 17 14:11:03 UTC 2016


On Fri, Oct 14, 2016 at 04:23:07PM -0400, John Ferlan wrote:
> Add the secret object prior to the chardev tcp so the 'passwordid=' can
> be added if the domain XML has a <secret> for the chardev TLS.
> 
> Signed-off-by: John Ferlan <jferlan at redhat.com>
> ---
>  src/qemu/qemu_command.c                            | 32 ++++++-
>  src/qemu/qemu_command.h                            |  1 +
>  src/qemu/qemu_domain.c                             | 99 +++++++++++++++++++++-
>  src/qemu/qemu_domain.h                             | 16 +++-
>  src/qemu/qemu_hotplug.c                            |  1 +
>  src/qemu/qemu_process.c                            |  6 +-
>  ...xml2argv-serial-tcp-tlsx509-secret-chardev.args | 38 +++++++++
>  ...uxml2argv-serial-tcp-tlsx509-secret-chardev.xml | 50 +++++++++++
>  tests/qemuxml2argvtest.c                           | 18 ++++
>  9 files changed, 252 insertions(+), 9 deletions(-)
>  create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-tlsx509-secret-chardev.args
>  create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-tlsx509-secret-chardev.xml
> 
> diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
> index aaf7018..b2dfee0 100644
> --- a/src/qemu/qemu_command.c
> +++ b/src/qemu/qemu_command.c
> @@ -695,6 +695,7 @@ qemuBuildRBDSecinfoURI(virBufferPtr buf,
>   * @tlspath: path to the TLS credentials
>   * @listen: boolen listen for client or server setting
>   * @verifypeer: boolean to enable peer verification (form of authorization)
> + * @secalias: if one exists, the alias of the security object for passwordid
>   * @qemuCaps: capabilities
>   * @propsret: json properties to return
>   *
> @@ -706,6 +707,7 @@ int
>  qemuBuildTLSx509BackendProps(const char *tlspath,
>                               bool isListen,
>                               bool verifypeer,
> +                             const char *secalias,
>                               virQEMUCapsPtr qemuCaps,
>                               virJSONValuePtr *propsret)
>  {
> @@ -731,6 +733,10 @@ qemuBuildTLSx509BackendProps(const char *tlspath,
>                                   NULL) < 0)
>          goto cleanup;
>  
> +    if (secalias &&
> +        virJSONValueObjectAdd(*propsret, "s:passwordid", secalias, NULL) < 0)
> +        goto cleanup;
> +
>      ret = 0;
>  
>   cleanup:
> @@ -745,6 +751,7 @@ qemuBuildTLSx509BackendProps(const char *tlspath,
>   * @tlspath: path to the TLS credentials
>   * @listen: boolen listen for client or server setting
>   * @verifypeer: boolean to enable peer verification (form of authorization)
> + * @addpasswordid: boolean to handle adding passwordid to object
>   * @inalias: Alias for the parent to generate object alias
>   * @qemuCaps: capabilities
>   *
> @@ -757,6 +764,7 @@ qemuBuildTLSx509CommandLine(virCommandPtr cmd,
>                              const char *tlspath,
>                              bool isListen,
>                              bool verifypeer,
> +                            bool addpasswordid,
>                              const char *inalias,
>                              virQEMUCapsPtr qemuCaps)
>  {
> @@ -764,11 +772,16 @@ qemuBuildTLSx509CommandLine(virCommandPtr cmd,
>      char *objalias = NULL;
>      virJSONValuePtr props = NULL;
>      char *tmp = NULL;
> +    char *secalias = NULL;
>  
> -    if (qemuBuildTLSx509BackendProps(tlspath, isListen, verifypeer,
> -                                     qemuCaps, &props) < 0)
> +    if (addpasswordid &&
> +        !(secalias = qemuDomainGetSecretAESAlias(inalias, false)))
>          return -1;
>  
> +    if (qemuBuildTLSx509BackendProps(tlspath, isListen, verifypeer, secalias,
> +                                     qemuCaps, &props) < 0)
> +        goto cleanup;
> +
>      if (!(objalias = qemuAliasTLSObjFromChardevAlias(inalias)))
>          goto cleanup;
>  
> @@ -784,6 +797,7 @@ qemuBuildTLSx509CommandLine(virCommandPtr cmd,
>      virJSONValueFree(props);
>      VIR_FREE(objalias);
>      VIR_FREE(tmp);
> +    VIR_FREE(secalias);
>      return ret;
>  }
>  
> @@ -4946,6 +4960,7 @@ qemuBuildChrChardevStr(virLogManagerPtr logManager,
>              if (qemuBuildTLSx509CommandLine(cmd, cfg->chardevTLSx509certdir,
>                                              dev->data.tcp.listen,
>                                              cfg->chardevTLSx509verify,
> +                                            !!cfg->chardevTLSx509secretUUID,
>                                              alias, qemuCaps) < 0)
>                  goto error;
>  
> @@ -8542,6 +8557,19 @@ qemuBuildSerialCommandLine(virLogManagerPtr logManager,
>  
>          /* Use -chardev with -device if they are available */
>          if (virQEMUCapsSupportsChardev(def, qemuCaps, serial)) {
> +            qemuDomainChardevPrivatePtr chardevPriv =
> +                QEMU_DOMAIN_CHARDEV_PRIVATE(serial);
> +            qemuDomainSecretInfoPtr secinfo = chardevPriv->secinfo;
> +
> +            /* Add the secret object first if necessary. The
> +             * secinfo is added only to a TCP serial device during
> +             * qemuDomainSecretChardevPrepare. Subsequent called
> +             * functions can just check the config fields */
> +            if (cfg->chardevTLS && cfg->chardevTLSx509secretUUID &&
> +                serial->source.type == VIR_DOMAIN_CHR_TYPE_TCP &&

This needs to test also serial->source.data.tcp.haveTLS.

> +                qemuBuildObjectSecretCommandLine(cmd, secinfo) < 0)
> +                return -1;
> +
>              if (!(devstr = qemuBuildChrChardevStr(logManager, cmd, cfg, def,
>                                                    &serial->source,
>                                                    serial->info.alias,
> diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h
> index 2f2a6ff..a793fb6 100644
> --- a/src/qemu/qemu_command.h
> +++ b/src/qemu/qemu_command.h
> @@ -69,6 +69,7 @@ int qemuBuildSecretInfoProps(qemuDomainSecretInfoPtr secinfo,
>  int qemuBuildTLSx509BackendProps(const char *tlspath,
>                                   bool isListen,
>                                   bool verifypeer,
> +                                 const char *secalias,
>                                   virQEMUCapsPtr qemuCaps,
>                                   virJSONValuePtr *propsret);
>  
> diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
> index a07f981..02c67ae 100644
> --- a/src/qemu/qemu_domain.c
> +++ b/src/qemu/qemu_domain.c
> @@ -1042,7 +1042,8 @@ qemuDomainSecretSetup(virConnectPtr conn,
>      if (virCryptoHaveCipher(VIR_CRYPTO_CIPHER_AES256CBC) &&
>          virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_OBJECT_SECRET) &&
>          (secretUsageType == VIR_SECRET_USAGE_TYPE_CEPH ||
> -         secretUsageType == VIR_SECRET_USAGE_TYPE_VOLUME)) {
> +         secretUsageType == VIR_SECRET_USAGE_TYPE_VOLUME ||
> +         secretUsageType == VIR_SECRET_USAGE_TYPE_TLS)) {
>          if (qemuDomainSecretAESSetup(conn, priv, secinfo, srcalias,
>                                       secretUsageType, username,
>                                       seclookupdef, isLuks) < 0)
> @@ -1223,6 +1224,91 @@ qemuDomainSecretHostdevPrepare(virConnectPtr conn,
>  }
>  
>  
> +/* qemuDomainSecretChardevDestroy:
> + * @disk: Pointer to a chardev definition
> + *
> + * Clear and destroy memory associated with the secret
> + */
> +void
> +qemuDomainSecretChardevDestroy(virDomainChrDefPtr chardev)
> +{
> +    qemuDomainChardevPrivatePtr chardevPriv =
> +        QEMU_DOMAIN_CHARDEV_PRIVATE(chardev);
> +
> +    if (!chardevPriv || !chardevPriv->secinfo)
> +        return;
> +
> +    qemuDomainSecretInfoFree(&chardevPriv->secinfo);
> +}
> +
> +
> +/* qemuDomainSecretChardevPrepare:
> + * @conn: Pointer to connection
> + * @driver: Pointer to driver object
> + * @priv: pointer to domain private object
> + * @chardev: Pointer to a chardev definition
> + *
> + * For a serial TCP character device, generate a qemuDomainSecretInfo to be
> + * used by the command line code to generate the secret for the tls-creds
> + * to use.
> + *
> + * Returns 0 on success, -1 on failure
> + */
> +int
> +qemuDomainSecretChardevPrepare(virConnectPtr conn,
> +                               virQEMUDriverPtr driver,
> +                               qemuDomainObjPrivatePtr priv,
> +                               virDomainChrDefPtr chardev)
> +{
> +    virQEMUDriverConfigPtr cfg;
> +    virSecretLookupTypeDef seclookupdef = {0};
> +    qemuDomainSecretInfoPtr secinfo = NULL;
> +
> +    if (!conn || chardev->deviceType != VIR_DOMAIN_CHR_DEVICE_TYPE_SERIAL ||

The check for !conn is redundant because the declaration uses
ATTRIBUTE_NONNULL for the first attribute.

> +        chardev->source.type != VIR_DOMAIN_CHR_TYPE_TCP)
> +        return 0;
> +
> +    cfg = virQEMUDriverGetConfig(driver);
> +    if (cfg->chardevTLS && cfg->chardevTLSx509secretUUID) {
> +        qemuDomainChardevPrivatePtr chardevPriv =
> +            QEMU_DOMAIN_CHARDEV_PRIVATE(chardev);
> +
> +        if (virUUIDParse(cfg->chardevTLSx509secretUUID,
> +                         seclookupdef.u.uuid) < 0) {
> +            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
> +                           _("malformed chardev TLS secret uuid in qemu.conf"));
> +            goto error;
> +        }
> +        seclookupdef.type = VIR_SECRET_LOOKUP_TYPE_UUID;
> +
> +        if (VIR_ALLOC(secinfo) < 0)
> +            goto error;
> +
> +        if (qemuDomainSecretSetup(conn, priv, secinfo, chardev->info.alias,
> +                                  VIR_SECRET_USAGE_TYPE_TLS, NULL,
> +                                  &seclookupdef, false) < 0)
> +            goto error;
> +
> +        if (secinfo->type == VIR_DOMAIN_SECRET_INFO_TYPE_PLAIN) {
> +            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
> +                           _("TLS X.509 requires encrypted secrets "
> +                             "to be supported"));
> +            goto error;
> +        }
> +
> +        chardevPriv->secinfo = secinfo;
> +    }
> +
> +    virObjectUnref(cfg);
> +    return 0;
> +
> + error:
> +    virObjectUnref(cfg);
> +    qemuDomainSecretInfoFree(&secinfo);
> +    return -1;
> +}
> +
> +
>  /* qemuDomainSecretDestroy:
>   * @vm: Domain object
>   *
> @@ -1239,11 +1325,15 @@ qemuDomainSecretDestroy(virDomainObjPtr vm)
>  
>      for (i = 0; i < vm->def->nhostdevs; i++)
>          qemuDomainSecretHostdevDestroy(vm->def->hostdevs[i]);
> +
> +    for (i = 0; i < vm->def->nserials; i++)
> +        qemuDomainSecretChardevDestroy(vm->def->serials[i]);
>  }
>  
>  
>  /* qemuDomainSecretPrepare:
>   * @conn: Pointer to connection
> + * @driver: Pointer to driver object
>   * @vm: Domain object
>   *
>   * For any objects that may require an auth/secret setup, create a
> @@ -1256,6 +1346,7 @@ qemuDomainSecretDestroy(virDomainObjPtr vm)
>   */
>  int
>  qemuDomainSecretPrepare(virConnectPtr conn,
> +                        virQEMUDriverPtr driver,
>                          virDomainObjPtr vm)
>  {
>      qemuDomainObjPrivatePtr priv = vm->privateData;
> @@ -1272,6 +1363,12 @@ qemuDomainSecretPrepare(virConnectPtr conn,
>              return -1;
>      }
>  
> +    for (i = 0; i < vm->def->nserials; i++) {
> +        if (qemuDomainSecretChardevPrepare(conn, driver, priv,
> +                                           vm->def->serials[i]) < 0)
> +            return -1;
> +    }
> +
>      return 0;
>  }
>  
> diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
> index 707a995..cc063d1 100644
> --- a/src/qemu/qemu_domain.h
> +++ b/src/qemu/qemu_domain.h
> @@ -726,11 +726,23 @@ int qemuDomainSecretHostdevPrepare(virConnectPtr conn,
>                                     virDomainHostdevDefPtr hostdev)
>      ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3);
>  
> +void qemuDomainSecretChardevDestroy(virDomainChrDefPtr chardev)
> +    ATTRIBUTE_NONNULL(1);
> +
> +int qemuDomainSecretChardevPrepare(virConnectPtr conn,
> +                                   virQEMUDriverPtr driver,
> +                                   qemuDomainObjPrivatePtr priv,
> +                                   virDomainChrDefPtr chardev)
> +    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3)
> +    ATTRIBUTE_NONNULL(4);
> +
>  void qemuDomainSecretDestroy(virDomainObjPtr vm)
>      ATTRIBUTE_NONNULL(1);
>  
> -int qemuDomainSecretPrepare(virConnectPtr conn, virDomainObjPtr vm)
> -    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
> +int qemuDomainSecretPrepare(virConnectPtr conn,
> +                            virQEMUDriverPtr driver,
> +                            virDomainObjPtr vm)
> +    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3);
>  
>  int qemuDomainDefValidateDiskLunSource(const virStorageSource *src)
>      ATTRIBUTE_NONNULL(1);
> diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
> index f4d7c17..aad7fa1 100644
> --- a/src/qemu/qemu_hotplug.c
> +++ b/src/qemu/qemu_hotplug.c
> @@ -1734,6 +1734,7 @@ int qemuDomainAttachChrDevice(virQEMUDriverPtr driver,
>          if (qemuBuildTLSx509BackendProps(cfg->chardevTLSx509certdir,
>                                           dev->data.tcp.listen,
>                                           cfg->chardevTLSx509verify,
> +                                         NULL,
>                                           priv->qemuCaps,
>                                           &tlsProps) < 0)
>              goto cleanup;
> diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
> index 0f5a11b..643741d 100644
> --- a/src/qemu/qemu_process.c
> +++ b/src/qemu/qemu_process.c
> @@ -5092,7 +5092,6 @@ qemuProcessPrepareDomain(virConnectPtr conn,
>      size_t i;
>      char *nodeset = NULL;
>      qemuDomainObjPrivatePtr priv = vm->privateData;
> -    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);

The cfg cleanup could be moved to separate patch.

>      virCapsPtr caps;
>  
>      if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
> @@ -5158,8 +5157,8 @@ qemuProcessPrepareDomain(virConnectPtr conn,
>      if (qemuDomainMasterKeyCreate(vm) < 0)
>          goto cleanup;
>  
> -    VIR_DEBUG("Add secrets to disks and hostdevs");
> -    if (qemuDomainSecretPrepare(conn, vm) < 0)
> +    VIR_DEBUG("Add secrets to disks, hostdevs, and chardevs");
> +    if (qemuDomainSecretPrepare(conn, driver, vm) < 0)
>          goto cleanup;
>  
>      for (i = 0; i < vm->def->nchannels; i++) {
> @@ -5188,7 +5187,6 @@ qemuProcessPrepareDomain(virConnectPtr conn,
>   cleanup:
>      VIR_FREE(nodeset);
>      virObjectUnref(caps);
> -    virObjectUnref(cfg);
>      return ret;
>  }
>  
> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-tlsx509-secret-chardev.args b/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-tlsx509-secret-chardev.args
> new file mode 100644
> index 0000000..5859c74
> --- /dev/null
> +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-tlsx509-secret-chardev.args
> @@ -0,0 +1,38 @@
> +LC_ALL=C \
> +PATH=/bin \
> +HOME=/home/test \
> +USER=test \
> +LOGNAME=test \
> +QEMU_AUDIO_DRV=none \
> +/usr/bin/qemu \
> +-name QEMUGuest1 \
> +-S \
> +-object secret,id=masterKey0,format=raw,\
> +file=/tmp/lib/domain--1-QEMUGuest1/master-key.aes \
> +-M pc \
> +-m 214 \
> +-smp 1,sockets=1,cores=1,threads=1 \
> +-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
> +-nographic \
> +-nodefconfig \
> +-nodefaults \
> +-chardev socket,id=charmonitor,path=/tmp/lib/domain--1-QEMUGuest1/monitor.sock,\
> +server,nowait \
> +-mon chardev=charmonitor,id=monitor,mode=readline \
> +-no-acpi \
> +-boot c \
> +-usb \
> +-drive file=/dev/HostVG/QEMUGuest1,format=raw,if=none,id=drive-ide0-0-0 \
> +-device ide-drive,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0 \
> +-chardev udp,id=charserial0,host=127.0.0.1,port=2222,localaddr=127.0.0.1,\
> +localport=1111 \
> +-device isa-serial,chardev=charserial0,id=serial0 \
> +-object secret,id=serial1-secret0,\
> +data=9eao5F8qtkGt+seB1HYivWIxbtwUu6MQtg1zpj/oDtUsPr1q8wBYM91uEHCn6j/1,\
> +keyid=masterKey0,iv=AAECAwQFBgcICQoLDA0ODw==,format=base64 \
> +-object tls-creds-x509,id=objserial1_tls0,dir=/etc/pki/libvirt-chardev,\
> +endpoint=client,verify-peer=yes,passwordid=serial1-secret0 \
> +-chardev socket,id=charserial1,host=127.0.0.1,port=5555,\
> +tls-creds=objserial1_tls0 \
> +-device isa-serial,chardev=charserial1,id=serial1 \
> +-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3
> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-tlsx509-secret-chardev.xml b/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-tlsx509-secret-chardev.xml
> new file mode 100644
> index 0000000..23c244b
> --- /dev/null
> +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-tlsx509-secret-chardev.xml
> @@ -0,0 +1,50 @@
> +<domain type='qemu'>
> +  <name>QEMUGuest1</name>
> +  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
> +  <memory unit='KiB'>219136</memory>
> +  <currentMemory unit='KiB'>219136</currentMemory>
> +  <vcpu placement='static'>1</vcpu>
> +  <os>
> +    <type arch='i686' machine='pc'>hvm</type>
> +    <boot dev='hd'/>
> +  </os>
> +  <clock offset='utc'/>
> +  <on_poweroff>destroy</on_poweroff>
> +  <on_reboot>restart</on_reboot>
> +  <on_crash>destroy</on_crash>
> +  <devices>
> +    <emulator>/usr/bin/qemu</emulator>
> +    <disk type='block' device='disk'>
> +      <source dev='/dev/HostVG/QEMUGuest1'/>
> +      <target dev='hda' bus='ide'/>
> +      <address type='drive' controller='0' bus='0' target='0' unit='0'/>
> +    </disk>
> +    <controller type='usb' index='0'>
> +      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
> +    </controller>
> +    <controller type='ide' index='0'>
> +      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
> +    </controller>
> +    <controller type='pci' index='0' model='pci-root'/>
> +    <serial type='udp'>
> +      <source mode='bind' host='127.0.0.1' service='1111'/>
> +      <source mode='connect' host='127.0.0.1' service='2222'/>
> +      <target port='0'/>
> +    </serial>
> +    <serial type='tcp'>
> +      <source mode='connect' host='127.0.0.1' service='5555' tls='yes'/>
> +      <protocol type='raw'/>
> +      <target port='0'/>
> +    </serial>
> +    <console type='udp'>
> +      <source mode='bind' host='127.0.0.1' service='1111'/>
> +      <source mode='connect' host='127.0.0.1' service='2222'/>
> +      <target type='serial' port='0'/>
> +    </console>
> +    <input type='mouse' bus='ps2'/>
> +    <input type='keyboard' bus='ps2'/>
> +    <memballoon model='virtio'>
> +      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
> +    </memballoon>
> +  </devices>
> +</domain>
> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
> index c65c769..1ca91d3 100644
> --- a/tests/qemuxml2argvtest.c
> +++ b/tests/qemuxml2argvtest.c
> @@ -1165,6 +1165,24 @@ mymain(void)
>      DO_TEST("serial-tcp-tlsx509-chardev-notls",
>              QEMU_CAPS_CHARDEV, QEMU_CAPS_NODEFCONFIG,
>              QEMU_CAPS_OBJECT_TLS_CREDS_X509);
> +    VIR_FREE(driver.config->chardevTLSx509certdir);
> +    if (VIR_STRDUP_QUIET(driver.config->chardevTLSx509certdir, "/etc/pki/libvirt-chardev") < 0)
> +        return EXIT_FAILURE;
> +    driver.config->chardevTLSx509verify = 1;

Setting the chardevTLSx509verify is not strictly required to test the generated
command line if secret is required.  The verify feature should has its own test
case.

Pavel

> +    if (VIR_STRDUP_QUIET(driver.config->chardevTLSx509secretUUID,
> +                         "6fd3f62d-9fe7-4a4e-a869-7acd6376d8ea") < 0)
> +        return EXIT_FAILURE;
> +# ifdef HAVE_GNUTLS_CIPHER_ENCRYPT
> +    DO_TEST("serial-tcp-tlsx509-secret-chardev",
> +            QEMU_CAPS_CHARDEV, QEMU_CAPS_NODEFCONFIG,
> +            QEMU_CAPS_OBJECT_SECRET,
> +            QEMU_CAPS_OBJECT_TLS_CREDS_X509);
> +# else
> +    DO_TEST_FAILURE("serial-tcp-tlsx509-secret-chardev",
> +                    QEMU_CAPS_CHARDEV, QEMU_CAPS_NODEFCONFIG,
> +                    QEMU_CAPS_OBJECT_SECRET,
> +                    QEMU_CAPS_OBJECT_TLS_CREDS_X509);
> +# endif
>      driver.config->chardevTLS = 0;
>      VIR_FREE(driver.config->chardevTLSx509certdir);
>      DO_TEST("serial-many-chardev",
> -- 
> 2.7.4
> 
> --
> libvir-list mailing list
> libvir-list at redhat.com
> https://www.redhat.com/mailman/listinfo/libvir-list
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: Digital signature
URL: <http://listman.redhat.com/archives/libvir-list/attachments/20161017/6085ba5b/attachment-0001.sig>


More information about the libvir-list mailing list