[libvirt] [PATCH 1/2] Allow certificate sanity checking to be disabled
by Daniel P. Berrange
From: "Daniel P. Berrange" <berrange(a)redhat.com>
When libvirtd starts it it will sanity check its own certs,
and before libvirt clients connect to a remote server they
will sanity check their own certs. This patch allows such
sanity checking to be skipped. There is no strong reason to
need to do this, other than to bypass possible libvirt bugs
in sanity checking, or for testing purposes.
libvirt.conf gains tls_no_sanity_certificate parameter to
go along with tls_no_verify_certificate. The remote driver
client URIs gain a no_sanity URI parameter
* daemon/test_libvirtd.aug, daemon/libvirtd.conf,
daemon/libvirtd.c, daemon/libvirtd.aug: Add parameter to
allow cert sanity checks to be skipped
* src/remote/remote_driver.c: Add no_sanity parameter to
skip cert checks
* src/rpc/virnettlscontext.c, src/rpc/virnettlscontext.h:
Add new parameter for skipping sanity checks independantly
of skipping session cert validation checks
---
daemon/libvirtd.aug | 1 +
daemon/libvirtd.c | 4 ++++
daemon/libvirtd.conf | 9 +++++++++
daemon/test_libvirtd.aug | 2 ++
src/remote/remote_driver.c | 15 +++++++++------
src/rpc/virnettlscontext.c | 36 +++++++++++++++++++++++-------------
src/rpc/virnettlscontext.h | 4 ++++
7 files changed, 52 insertions(+), 19 deletions(-)
diff --git a/daemon/libvirtd.aug b/daemon/libvirtd.aug
index 0e06142..3f47ebb 100644
--- a/daemon/libvirtd.aug
+++ b/daemon/libvirtd.aug
@@ -48,6 +48,7 @@ module Libvirtd =
| str_entry "crl_file"
let authorization_entry = bool_entry "tls_no_verify_certificate"
+ | bool_entry "tls_no_sanity_certificate"
| str_array_entry "tls_allowed_dn_list"
| str_array_entry "sasl_allowed_username_list"
diff --git a/daemon/libvirtd.c b/daemon/libvirtd.c
index f2f3a4e..9e044e2 100644
--- a/daemon/libvirtd.c
+++ b/daemon/libvirtd.c
@@ -120,6 +120,7 @@ struct daemonConfig {
char *mdns_name;
int tls_no_verify_certificate;
+ int tls_no_sanity_certificate;
char **tls_allowed_dn_list;
char **sasl_allowed_username_list;
@@ -535,12 +536,14 @@ static int daemonSetupNetworking(virNetServerPtr srv,
config->cert_file,
config->key_file,
(const char *const*)config->tls_allowed_dn_list,
+ config->tls_no_sanity_certificate ? false : true,
config->tls_no_verify_certificate ? false : true)))
goto error;
} else {
if (!(ctxt = virNetTLSContextNewServerPath(NULL,
!privileged,
(const char *const*)config->tls_allowed_dn_list,
+ config->tls_no_sanity_certificate ? false : true,
config->tls_no_verify_certificate ? false : true)))
goto error;
}
@@ -1054,6 +1057,7 @@ daemonConfigLoad(struct daemonConfig *data,
GET_CONF_INT (conf, filename, mdns_adv);
GET_CONF_STR (conf, filename, mdns_name);
+ GET_CONF_INT (conf, filename, tls_no_sanity_certificate);
GET_CONF_INT (conf, filename, tls_no_verify_certificate);
GET_CONF_STR (conf, filename, key_file);
diff --git a/daemon/libvirtd.conf b/daemon/libvirtd.conf
index 3a071b0..217f2f4 100644
--- a/daemon/libvirtd.conf
+++ b/daemon/libvirtd.conf
@@ -187,6 +187,15 @@
#
+# Flag to disable verification of our own server certificates
+#
+# When libvirtd starts it performs some sanity checks against
+# its own certificates.
+#
+# Default is to always sanity. Uncommenting this will disable
+# sanity checks which is not a good idea
+#tls_no_sanity_certificate = 1
+
# Flag to disable verification of client certificates
#
# Client certificate verification is the primary authentication mechanism.
diff --git a/daemon/test_libvirtd.aug b/daemon/test_libvirtd.aug
index 5f8b644..58b7170 100644
--- a/daemon/test_libvirtd.aug
+++ b/daemon/test_libvirtd.aug
@@ -193,6 +193,7 @@ crl_file = \"/etc/pki/CA/crl.pem\"
# Default is to always verify. Uncommenting this will disable
# verification - make sure an IP whitelist is set
tls_no_verify_certificate = 1
+tls_no_sanity_certificate = 1
# A whitelist of allowed x509 Distinguished Names
@@ -468,6 +469,7 @@ audit_level = 2
{ "#comment" = "Default is to always verify. Uncommenting this will disable" }
{ "#comment" = "verification - make sure an IP whitelist is set" }
{ "tls_no_verify_certificate" = "1" }
+ { "tls_no_sanity_certificate" = "1" }
{ "#empty" }
{ "#empty" }
{ "#comment" = "A whitelist of allowed x509 Distinguished Names" }
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index ec4133b..7993d50 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -351,7 +351,7 @@ doRemoteOpen (virConnectPtr conn,
*/
char *name = NULL, *command = NULL, *sockname = NULL, *netcat = NULL;
char *port = NULL, *authtype = NULL, *username = NULL;
- int no_verify = 0, no_tty = 0;
+ bool sanity = true, verify = true, tty = true;
char *pkipath = NULL;
/* Return code from this function, and the private data. */
@@ -425,11 +425,14 @@ doRemoteOpen (virConnectPtr conn,
netcat = strdup (var->value);
if (!netcat) goto out_of_memory;
var->ignore = 1;
+ } else if (STRCASEEQ (var->name, "no_sanity")) {
+ sanity = atoi(var->value) == 0;
+ var->ignore = 1;
} else if (STRCASEEQ (var->name, "no_verify")) {
- no_verify = atoi (var->value);
+ verify = atoi (var->value) == 0;
var->ignore = 1;
} else if (STRCASEEQ (var->name, "no_tty")) {
- no_tty = atoi (var->value);
+ tty = atoi (var->value) == 0;
var->ignore = 1;
} else if (STRCASEEQ(var->name, "pkipath")) {
VIR_FREE(pkipath);
@@ -509,7 +512,7 @@ doRemoteOpen (virConnectPtr conn,
case trans_tls:
priv->tls = virNetTLSContextNewClientPath(pkipath,
geteuid() != 0 ? true : false,
- no_verify ? false : true);
+ sanity, verify);
if (!priv->tls)
goto failed;
priv->is_secure = 1;
@@ -579,8 +582,8 @@ doRemoteOpen (virConnectPtr conn,
port,
command,
username,
- no_tty,
- no_verify,
+ !tty,
+ !verify,
netcat ? netcat : "nc",
sockname)))
goto failed;
diff --git a/src/rpc/virnettlscontext.c b/src/rpc/virnettlscontext.c
index 5c94df6..bde4e7a 100644
--- a/src/rpc/virnettlscontext.c
+++ b/src/rpc/virnettlscontext.c
@@ -382,7 +382,7 @@ virNetTLSContextCheckCertDN(gnutls_x509_crt_t cert,
certFile, gnutls_strerror(ret));
return -1;
}
-
+ VIR_DEBUG("Peer DN is %s", name);
if (whitelist &&
virNetTLSContextCheckCertDNWhitelist(name, whitelist) <= 0)
return -1;
@@ -637,6 +637,7 @@ static virNetTLSContextPtr virNetTLSContextNew(const char *cacert,
const char *cert,
const char *key,
const char *const*x509dnWhitelist,
+ bool sanityCheckCert,
bool requireValidCert,
bool isServer)
{
@@ -644,8 +645,8 @@ static virNetTLSContextPtr virNetTLSContextNew(const char *cacert,
char *gnutlsdebug;
int err;
- VIR_DEBUG("cacert=%s cacrl=%s cert=%s key=%s requireValid=%d isServer=%d",
- cacert, NULLSTR(cacrl), cert, key, requireValidCert, isServer);
+ VIR_DEBUG("cacert=%s cacrl=%s cert=%s key=%s sanityCheckCert=%d requireValid=%d isServer=%d",
+ cacert, NULLSTR(cacrl), cert, key, sanityCheckCert, requireValidCert, isServer);
if (VIR_ALLOC(ctxt) < 0) {
virReportOOMError();
@@ -675,7 +676,7 @@ static virNetTLSContextPtr virNetTLSContextNew(const char *cacert,
goto error;
}
- if (requireValidCert &&
+ if (sanityCheckCert &&
virNetTLSContextSanityCheckCredentials(isServer, cacert, cert) < 0)
goto error;
@@ -851,6 +852,7 @@ out_of_memory:
static virNetTLSContextPtr virNetTLSContextNewPath(const char *pkipath,
bool tryUserPkiPath,
const char *const*x509dnWhitelist,
+ bool sanityCheckCert,
bool requireValidCert,
bool isServer)
{
@@ -862,7 +864,8 @@ static virNetTLSContextPtr virNetTLSContextNewPath(const char *pkipath,
return NULL;
ctxt = virNetTLSContextNew(cacert, cacrl, cert, key,
- x509dnWhitelist, requireValidCert, isServer);
+ x509dnWhitelist, sanityCheckCert,
+ requireValidCert, isServer);
VIR_FREE(cacert);
VIR_FREE(cacrl);
@@ -875,18 +878,20 @@ static virNetTLSContextPtr virNetTLSContextNewPath(const char *pkipath,
virNetTLSContextPtr virNetTLSContextNewServerPath(const char *pkipath,
bool tryUserPkiPath,
const char *const*x509dnWhitelist,
+ bool sanityCheckCert,
bool requireValidCert)
{
- return virNetTLSContextNewPath(pkipath, tryUserPkiPath,
- x509dnWhitelist, requireValidCert, true);
+ return virNetTLSContextNewPath(pkipath, tryUserPkiPath, x509dnWhitelist,
+ sanityCheckCert, requireValidCert, true);
}
virNetTLSContextPtr virNetTLSContextNewClientPath(const char *pkipath,
bool tryUserPkiPath,
+ bool sanityCheckCert,
bool requireValidCert)
{
- return virNetTLSContextNewPath(pkipath, tryUserPkiPath,
- NULL, requireValidCert, false);
+ return virNetTLSContextNewPath(pkipath, tryUserPkiPath, NULL,
+ sanityCheckCert, requireValidCert, false);
}
@@ -895,10 +900,11 @@ virNetTLSContextPtr virNetTLSContextNewServer(const char *cacert,
const char *cert,
const char *key,
const char *const*x509dnWhitelist,
+ bool sanityCheckCert,
bool requireValidCert)
{
- return virNetTLSContextNew(cacert, cacrl, cert, key,
- x509dnWhitelist, requireValidCert, true);
+ return virNetTLSContextNew(cacert, cacrl, cert, key, x509dnWhitelist,
+ sanityCheckCert, requireValidCert, true);
}
@@ -906,10 +912,11 @@ virNetTLSContextPtr virNetTLSContextNewClient(const char *cacert,
const char *cacrl,
const char *cert,
const char *key,
+ bool sanityCheckCert,
bool requireValidCert)
{
- return virNetTLSContextNew(cacert, cacrl, key, cert,
- NULL, requireValidCert, false);
+ return virNetTLSContextNew(cacert, cacrl, cert, key, NULL,
+ sanityCheckCert, requireValidCert, false);
}
@@ -1047,11 +1054,14 @@ int virNetTLSContextCheckCertificate(virNetTLSContextPtr ctxt,
virNetTLSSessionPtr sess)
{
if (virNetTLSContextValidCertificate(ctxt, sess) < 0) {
+ virErrorPtr err = virGetLastError();
+ VIR_WARN("Certificate check failed %s", err && err->message ? err->message : "<unknown>");
if (ctxt->requireValidCert) {
virNetError(VIR_ERR_AUTH_FAILED, "%s",
_("Failed to verify peer's certificate"));
return -1;
}
+ virResetLastError();
VIR_INFO("Ignoring bad certificate at user request");
}
return 0;
diff --git a/src/rpc/virnettlscontext.h b/src/rpc/virnettlscontext.h
index f23667f..641d67e 100644
--- a/src/rpc/virnettlscontext.h
+++ b/src/rpc/virnettlscontext.h
@@ -33,10 +33,12 @@ typedef virNetTLSSession *virNetTLSSessionPtr;
virNetTLSContextPtr virNetTLSContextNewServerPath(const char *pkipath,
bool tryUserPkiPath,
const char *const*x509dnWhitelist,
+ bool sanityCheckCert,
bool requireValidCert);
virNetTLSContextPtr virNetTLSContextNewClientPath(const char *pkipath,
bool tryUserPkiPath,
+ bool sanityCheckCert,
bool requireValidCert);
virNetTLSContextPtr virNetTLSContextNewServer(const char *cacert,
@@ -44,12 +46,14 @@ virNetTLSContextPtr virNetTLSContextNewServer(const char *cacert,
const char *cert,
const char *key,
const char *const*x509dnWhitelist,
+ bool sanityCheckCert,
bool requireValidCert);
virNetTLSContextPtr virNetTLSContextNewClient(const char *cacert,
const char *cacrl,
const char *cert,
const char *key,
+ bool sanityCheckCert,
bool requireValidCert);
void virNetTLSContextRef(virNetTLSContextPtr ctxt);
--
1.7.6
13 years, 4 months
[libvirt] [PATCH 1/4] Fix memory leaks in MDNS code
by Daniel P. Berrange
From: "Daniel P. Berrange" <berrange(a)redhat.com>
* src/rpc/virnetservermdns.c: Fix leaks
---
src/rpc/virnetservermdns.c | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/src/rpc/virnetservermdns.c b/src/rpc/virnetservermdns.c
index ff2d92d..335274a 100644
--- a/src/rpc/virnetservermdns.c
+++ b/src/rpc/virnetservermdns.c
@@ -583,6 +583,7 @@ void virNetServerMDNSFree(virNetServerMDNSPtr mdns)
group = tmp;
}
+ VIR_FREE(mdns->poller);
VIR_FREE(mdns);
}
@@ -601,6 +602,7 @@ void virNetServerMDNSGroupFree(virNetServerMDNSGroupPtr grp)
entry = tmp;
}
+ VIR_FREE(grp->name);
VIR_FREE(grp);
}
@@ -610,5 +612,6 @@ void virNetServerMDNSEntryFree(virNetServerMDNSEntryPtr entry)
if (!entry)
return;
+ VIR_FREE(entry->type);
VIR_FREE(entry);
}
--
1.7.6
13 years, 4 months
[libvirt] [PATCH 0/4] python: add some missing python bindings
by Taku Izumi
Hi all,
This patchset adds some missing python bindings.
The bindings for the following APIs are added:
- virDomainGetSchedulerParametersFlags
- virDomainSetSchedulerParametersFlags
- virDomainPinVcpusFlags
- virDomainGetVcpuPinInfo
*[PATCH 1/3] python: add Python binding for virDomainGetSchedulerParametersFlags API
*[PATCH 2/3] python: add Python binding for virDomainSetSchedulerParametersFlags API
*[PATCH 3/3] python: add Python binding for virDomainPinVcpusFlags API
*[PATCH 4/4] python: add Python binding for virDomainGetVcpuPinInfo API
Best regards,
Taku Izumi
--
Taku Izumi <izumi.taku(a)jp.fujitsu.com>
13 years, 4 months
[libvirt] [PATCH] virsh: use faster bit search
by Eric Blake
Now that gnulib gives us ffs, we might as well use it.
* tools/virsh.c (vshCmddefGetData): Use ffs rather than
count_one_bits.
---
tools/virsh.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/tools/virsh.c b/tools/virsh.c
index ef8dea3..0dcc66b 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -32,6 +32,7 @@
#include <inttypes.h>
#include <signal.h>
#include <poll.h>
+#include <strings.h>
#include <libxml/parser.h>
#include <libxml/tree.h>
@@ -57,7 +58,6 @@
#include "configmake.h"
#include "threads.h"
#include "command.h"
-#include "count-one-bits.h"
static char *progname;
@@ -12280,7 +12280,7 @@ vshCmddefGetData(const vshCmdDef *cmd, uint32_t *opts_need_arg,
return NULL;
/* Grab least-significant set bit */
- i = count_one_bits(*opts_need_arg ^ (*opts_need_arg - 1)) - 1;
+ i = ffs(*opts_need_arg) - 1;
opt = &cmd->opts[i];
if (opt->type != VSH_OT_ARGV)
*opts_need_arg &= ~(1 << i);
--
1.7.1
13 years, 4 months
[libvirt] [PATCH] vcpu: teach getVcpusFlags about current
by Eric Blake
Now that virDomainSetVcpusFlags knows about VIR_DOMAIN_AFFECT_CURRENT,
so should virDomainGetVcpusFlags.
Unfortunately, the virsh counterpart 'virsh vcpucount' has already
commandeered --current for a different meaning, so virsh does not
have a way to expose this new calling capability unless we either
break backward compatibility or consistency with other virsh commands
that take --live and --config.
* src/libvirt.c (virDomainGetVcpusFlags): Allow
VIR_DOMAIN_AFFECT_CURRENT.
* src/libxl/libxl_driver.c (libxlDomainGetVcpusFlags): Likewise.
* src/qemu/qemu_driver.c (qemudDomainGetVcpusFlags): Likewise.
* src/test/test_driver.c (testDomainGetVcpusFlags): Likewise.
* src/xen/xen_driver.c (xenUnifiedDomainGetVcpusFlags): Likewise.
---
In response to:
https://www.redhat.com/archives/libvir-list/2011-July/msg00967.html
src/libvirt.c | 4 ++--
src/libxl/libxl_driver.c | 29 +++++++++++++++++++++--------
src/qemu/qemu_driver.c | 29 +++++++++++++++++++++--------
src/test/test_driver.c | 31 +++++++++++++++++++++++--------
src/xen/xen_driver.c | 7 -------
5 files changed, 67 insertions(+), 33 deletions(-)
diff --git a/src/libvirt.c b/src/libvirt.c
index 4de718d..def3fb9 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -6951,8 +6951,8 @@ virDomainGetVcpusFlags(virDomainPtr domain, unsigned int flags)
return -1;
}
- /* Exactly one of these two flags should be set. */
- if (!(flags & VIR_DOMAIN_AFFECT_LIVE) == !(flags & VIR_DOMAIN_AFFECT_CONFIG)) {
+ /* At most one of these two flags should be set. */
+ if ((flags & VIR_DOMAIN_AFFECT_LIVE) && (flags & VIR_DOMAIN_AFFECT_CONFIG)) {
virLibDomainError(VIR_ERR_INVALID_ARG, __FUNCTION__);
goto error;
}
diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
index cc37d05..2e0d377 100644
--- a/src/libxl/libxl_driver.c
+++ b/src/libxl/libxl_driver.c
@@ -2327,18 +2327,12 @@ libxlDomainGetVcpusFlags(virDomainPtr dom, unsigned int flags)
virDomainObjPtr vm;
virDomainDefPtr def;
int ret = -1;
+ bool active;
virCheckFlags(VIR_DOMAIN_VCPU_LIVE |
VIR_DOMAIN_VCPU_CONFIG |
VIR_DOMAIN_VCPU_MAXIMUM, -1);
- /* Exactly one of LIVE or CONFIG must be set. */
- if (!(flags & VIR_DOMAIN_VCPU_LIVE) == !(flags & VIR_DOMAIN_VCPU_CONFIG)) {
- libxlError(VIR_ERR_INVALID_ARG,
- _("invalid flag combination: (0x%x)"), flags);
- return -1;
- }
-
libxlDriverLock(driver);
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
libxlDriverUnlock(driver);
@@ -2348,14 +2342,33 @@ libxlDomainGetVcpusFlags(virDomainPtr dom, unsigned int flags)
goto cleanup;
}
+ active = virDomainObjIsActive(vm);
+
+ if ((flags & (VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_CONFIG)) == 0) {
+ if (active)
+ flags |= VIR_DOMAIN_VCPU_LIVE;
+ else
+ flags |= VIR_DOMAIN_VCPU_CONFIG;
+ }
+ if ((flags & VIR_DOMAIN_VCPU_LIVE) && (flags & VIR_DOMAIN_VCPU_CONFIG)) {
+ libxlError(VIR_ERR_INVALID_ARG,
+ _("invalid flag combination: (0x%x)"), flags);
+ return -1;
+ }
+
if (flags & VIR_DOMAIN_VCPU_LIVE) {
- if (!virDomainObjIsActive(vm)) {
+ if (!active) {
libxlError(VIR_ERR_OPERATION_INVALID,
"%s", _("Domain is not running"));
goto cleanup;
}
def = vm->def;
} else {
+ if (!vm->persistent) {
+ libxlError(VIR_ERR_OPERATION_INVALID,
+ "%s", _("domain is transient"));
+ goto cleanup;
+ }
def = vm->newDef ? vm->newDef : vm->def;
}
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 1a3fbfb..536cd5c 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -3408,18 +3408,12 @@ qemudDomainGetVcpusFlags(virDomainPtr dom, unsigned int flags)
virDomainObjPtr vm;
virDomainDefPtr def;
int ret = -1;
+ bool active;
virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
VIR_DOMAIN_AFFECT_CONFIG |
VIR_DOMAIN_VCPU_MAXIMUM, -1);
- /* Exactly one of LIVE or CONFIG must be set. */
- if (!(flags & VIR_DOMAIN_AFFECT_LIVE) == !(flags & VIR_DOMAIN_AFFECT_CONFIG)) {
- qemuReportError(VIR_ERR_INVALID_ARG,
- _("invalid flag combination: (0x%x)"), flags);
- return -1;
- }
-
qemuDriverLock(driver);
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
qemuDriverUnlock(driver);
@@ -3432,14 +3426,33 @@ qemudDomainGetVcpusFlags(virDomainPtr dom, unsigned int flags)
goto cleanup;
}
+ active = virDomainObjIsActive(vm);
+
+ if ((flags & (VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_CONFIG)) == 0) {
+ if (active)
+ flags |= VIR_DOMAIN_VCPU_LIVE;
+ else
+ flags |= VIR_DOMAIN_VCPU_CONFIG;
+ }
+ if ((flags & VIR_DOMAIN_AFFECT_LIVE) && (flags & VIR_DOMAIN_AFFECT_CONFIG)) {
+ qemuReportError(VIR_ERR_INVALID_ARG,
+ _("invalid flag combination: (0x%x)"), flags);
+ return -1;
+ }
+
if (flags & VIR_DOMAIN_AFFECT_LIVE) {
- if (!virDomainObjIsActive(vm)) {
+ if (!active) {
qemuReportError(VIR_ERR_OPERATION_INVALID, "%s",
_("domain not active"));
goto cleanup;
}
def = vm->def;
} else {
+ if (!vm->persistent) {
+ qemuReportError(VIR_ERR_OPERATION_INVALID, "%s",
+ _("domain is transient"));
+ goto cleanup;
+ }
def = vm->newDef ? vm->newDef : vm->def;
}
diff --git a/src/test/test_driver.c b/src/test/test_driver.c
index 064a1cd..28da8e7 100644
--- a/src/test/test_driver.c
+++ b/src/test/test_driver.c
@@ -2067,18 +2067,12 @@ testDomainGetVcpusFlags(virDomainPtr domain, unsigned int flags)
virDomainObjPtr vm;
virDomainDefPtr def;
int ret = -1;
+ bool active;
virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
VIR_DOMAIN_AFFECT_CONFIG |
VIR_DOMAIN_VCPU_MAXIMUM, -1);
- /* Exactly one of LIVE or CONFIG must be set. */
- if (!(flags & VIR_DOMAIN_AFFECT_LIVE) == !(flags & VIR_DOMAIN_AFFECT_CONFIG)) {
- testError(VIR_ERR_INVALID_ARG,
- _("invalid flag combination: (0x%x)"), flags);
- return -1;
- }
-
testDriverLock(privconn);
vm = virDomainFindByUUID(&privconn->domains, domain->uuid);
testDriverUnlock(privconn);
@@ -2091,14 +2085,35 @@ testDomainGetVcpusFlags(virDomainPtr domain, unsigned int flags)
goto cleanup;
}
+ active = virDomainObjIsActive(vm);
+
+ if ((flags & (VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_CONFIG)) == 0) {
+ if (active)
+ flags |= VIR_DOMAIN_VCPU_LIVE;
+ else
+ flags |= VIR_DOMAIN_VCPU_CONFIG;
+ }
+ if ((flags & VIR_DOMAIN_AFFECT_LIVE) && (flags & VIR_DOMAIN_AFFECT_CONFIG)) {
+ testError(VIR_ERR_INVALID_ARG,
+ _("invalid flag combination: (0x%x)"), flags);
+ return -1;
+ }
+
+
+
if (flags & VIR_DOMAIN_AFFECT_LIVE) {
- if (!virDomainObjIsActive(vm)) {
+ if (!active) {
testError(VIR_ERR_OPERATION_INVALID, "%s",
_("domain not active"));
goto cleanup;
}
def = vm->def;
} else {
+ if (!vm->persistent) {
+ testError(VIR_ERR_OPERATION_INVALID, "%s",
+ _("domain is transient"));
+ goto cleanup;
+ }
def = vm->newDef ? vm->newDef : vm->def;
}
diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c
index dd1ba6c..0f8b660 100644
--- a/src/xen/xen_driver.c
+++ b/src/xen/xen_driver.c
@@ -1201,13 +1201,6 @@ xenUnifiedDomainGetVcpusFlags (virDomainPtr dom, unsigned int flags)
VIR_DOMAIN_VCPU_CONFIG |
VIR_DOMAIN_VCPU_MAXIMUM, -1);
- /* Exactly one of LIVE or CONFIG must be set. */
- if (!(flags & VIR_DOMAIN_VCPU_LIVE) == !(flags & VIR_DOMAIN_VCPU_CONFIG)) {
- xenUnifiedError(VIR_ERR_INVALID_ARG,
- _("invalid flag combination: (0x%x)"), flags);
- return -1;
- }
-
if (priv->opened[XEN_UNIFIED_XEND_OFFSET]) {
ret = xenDaemonDomainGetVcpusFlags(dom, flags);
if (ret != -2)
--
1.7.4.4
13 years, 4 months
[libvirt] [PATCH] python: Handle embedded NULL in stream.send data
by Cole Robinson
Otherwise things like volume upload are only useful with text data.
---
python/libvirt-override.c | 5 +++--
1 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/python/libvirt-override.c b/python/libvirt-override.c
index 9d1dac2..70e0238 100644
--- a/python/libvirt-override.c
+++ b/python/libvirt-override.c
@@ -4151,11 +4151,12 @@ libvirt_virStreamSend(PyObject *self ATTRIBUTE_UNUSED,
PyObject *pyobj_stream;
virStreamPtr stream;
char *data;
+ int datalen;
int ret;
int nbytes;
- if (!PyArg_ParseTuple(args, (char *) "Ozi:virStreamRecv",
- &pyobj_stream, &data, &nbytes)) {
+ if (!PyArg_ParseTuple(args, (char *) "Oz#i:virStreamRecv",
+ &pyobj_stream, &data, &datalen, &nbytes)) {
DEBUG("%s failed to parse tuple\n", __FUNCTION__);
return VIR_PY_INT_FAIL;
}
--
1.7.4.4
13 years, 4 months
[libvirt] [PATCH] util: change virFile*Pid functions to return < 0 on failure
by Laine Stump
Although most functions in libvirt return 0 on success and < 0 on
failure, there are a few functions lingering around that return errno
(a positive value) on failure, and sometimes code calling those
functions incorrectly assumes the <0 standard. I noticed one of these
the other day when auditing networkStartDhcpDaemon after Guido Gunther
found a place where success was improperly returned on failure (that
patch has been acked and is pending a push). The problem was that it
expected the return value from virFileReadPid to be < 0 on failure,
but it was actually positive (it was also neglected to set the return
code in this case, similar to the bug found by Guido).
This all led to the fact that *all* of the virFile*Pid functions in
util.c are returning errno on failure. This patch remedies that
problem by changing them all to return -errno on failure, and makes
any necessary changes to callers of the functions. (In the meantime, I
also properly set the return code on failure of virFileReadPid in
networkStartDhcpDaemon).
---
src/lxc/lxc_controller.c | 6 +++---
src/lxc/lxc_driver.c | 4 ++--
src/network/bridge_driver.c | 5 +++--
src/qemu/qemu_process.c | 2 +-
src/util/command.c | 2 +-
src/util/util.c | 30 +++++++++++++++---------------
tests/commandtest.c | 4 ++--
7 files changed, 27 insertions(+), 26 deletions(-)
diff --git a/src/lxc/lxc_controller.c b/src/lxc/lxc_controller.c
index 7eda7ef..99d9467 100644
--- a/src/lxc/lxc_controller.c
+++ b/src/lxc/lxc_controller.c
@@ -947,8 +947,8 @@ int main(int argc, char *argv[])
goto cleanup;
if (pid > 0) {
- if ((rc = virFileWritePid(LXC_STATE_DIR, name, pid)) != 0) {
- virReportSystemError(rc,
+ if ((rc = virFileWritePid(LXC_STATE_DIR, name, pid)) < 0) {
+ virReportSystemError(-rc,
_("Unable to write pid file '%s/%s.pid'"),
LXC_STATE_DIR, name);
_exit(1);
@@ -996,5 +996,5 @@ cleanup:
unlink(sockpath);
VIR_FREE(sockpath);
- return rc;
+ return -rc; /* rc is 0 or negative, but returns from main should be >=0 */
}
diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c
index 615d2c6..7d99d27 100644
--- a/src/lxc/lxc_driver.c
+++ b/src/lxc/lxc_driver.c
@@ -1612,8 +1612,8 @@ static int lxcVmStart(virConnectPtr conn,
goto cleanup;
/* And get its pid */
- if ((r = virFileReadPid(driver->stateDir, vm->def->name, &vm->pid)) != 0) {
- virReportSystemError(r,
+ if ((r = virFileReadPid(driver->stateDir, vm->def->name, &vm->pid)) < 0) {
+ virReportSystemError(-r,
_("Failed to read pid file %s/%s.pid"),
driver->stateDir, vm->def->name);
goto cleanup;
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index f242db8..b2b0b06 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -756,8 +756,9 @@ networkStartDhcpDaemon(virNetworkObjPtr network)
* pid
*/
- if (virFileReadPid(NETWORK_PID_DIR, network->def->name,
- &network->dnsmasqPid) < 0)
+ ret = virFileReadPid(NETWORK_PID_DIR, network->def->name,
+ &network->dnsmasqPid);
+ if (ret < 0)
goto cleanup;
ret = 0;
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 646215e..b87c320 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -2754,7 +2754,7 @@ int qemuProcessStart(virConnectPtr conn,
/* wait for qemu process to show up */
if (ret == 0) {
- if (virFileReadPidPath(priv->pidfile, &vm->pid)) {
+ if (virFileReadPidPath(priv->pidfile, &vm->pid) < 0) {
qemuReportError(VIR_ERR_INTERNAL_ERROR,
_("Domain %s didn't show up"), vm->def->name);
ret = -1;
diff --git a/src/util/command.c b/src/util/command.c
index 29ccaa4..475eb62 100644
--- a/src/util/command.c
+++ b/src/util/command.c
@@ -493,7 +493,7 @@ virExecWithHook(const char *const*argv,
}
if (pid > 0) {
- if (pidfile && virFileWritePidPath(pidfile,pid)) {
+ if (pidfile && (virFileWritePidPath(pidfile,pid) < 0)) {
kill(pid, SIGTERM);
usleep(500*1000);
kill(pid, SIGTERM);
diff --git a/src/util/util.c b/src/util/util.c
index d83215c..03a9e1a 100644
--- a/src/util/util.c
+++ b/src/util/util.c
@@ -1165,17 +1165,17 @@ int virFileWritePid(const char *dir,
char *pidfile = NULL;
if (name == NULL || dir == NULL) {
- rc = EINVAL;
+ rc = -EINVAL;
goto cleanup;
}
if (virFileMakePath(dir) < 0) {
- rc = errno;
+ rc = -errno;
goto cleanup;
}
if (!(pidfile = virFilePid(dir, name))) {
- rc = ENOMEM;
+ rc = -ENOMEM;
goto cleanup;
}
@@ -1196,18 +1196,18 @@ int virFileWritePidPath(const char *pidfile,
if ((fd = open(pidfile,
O_WRONLY | O_CREAT | O_TRUNC,
S_IRUSR | S_IWUSR)) < 0) {
- rc = errno;
+ rc = -errno;
goto cleanup;
}
if (!(file = VIR_FDOPEN(fd, "w"))) {
- rc = errno;
+ rc = -errno;
VIR_FORCE_CLOSE(fd);
goto cleanup;
}
if (fprintf(file, "%d", pid) < 0) {
- rc = errno;
+ rc = -errno;
goto cleanup;
}
@@ -1215,7 +1215,7 @@ int virFileWritePidPath(const char *pidfile,
cleanup:
if (VIR_FCLOSE(file) < 0)
- rc = errno;
+ rc = -errno;
return rc;
}
@@ -1230,18 +1230,18 @@ int virFileReadPidPath(const char *path,
*pid = 0;
if (!(file = fopen(path, "r"))) {
- rc = errno;
+ rc = -errno;
goto cleanup;
}
if (fscanf(file, "%d", pid) != 1) {
- rc = EINVAL;
+ rc = -EINVAL;
VIR_FORCE_FCLOSE(file);
goto cleanup;
}
if (VIR_FCLOSE(file) < 0) {
- rc = errno;
+ rc = -errno;
goto cleanup;
}
@@ -1261,12 +1261,12 @@ int virFileReadPid(const char *dir,
*pid = 0;
if (name == NULL || dir == NULL) {
- rc = EINVAL;
+ rc = -EINVAL;
goto cleanup;
}
if (!(pidfile = virFilePid(dir, name))) {
- rc = ENOMEM;
+ rc = -ENOMEM;
goto cleanup;
}
@@ -1284,17 +1284,17 @@ int virFileDeletePid(const char *dir,
char *pidfile = NULL;
if (name == NULL || dir == NULL) {
- rc = EINVAL;
+ rc = -EINVAL;
goto cleanup;
}
if (!(pidfile = virFilePid(dir, name))) {
- rc = ENOMEM;
+ rc = -ENOMEM;
goto cleanup;
}
if (unlink(pidfile) < 0 && errno != ENOENT)
- rc = errno;
+ rc = -errno;
cleanup:
VIR_FREE(pidfile);
diff --git a/tests/commandtest.c b/tests/commandtest.c
index 9ab446c..ef2850d 100644
--- a/tests/commandtest.c
+++ b/tests/commandtest.c
@@ -230,7 +230,7 @@ static int test4(const void *unused ATTRIBUTE_UNUSED)
goto cleanup;
}
- if (virFileReadPid(abs_builddir, "commandhelper", &pid) != 0) {
+ if (virFileReadPid(abs_builddir, "commandhelper", &pid) < 0) {
printf("cannot read pidfile\n");
goto cleanup;
}
@@ -686,7 +686,7 @@ static int test18(const void *unused ATTRIBUTE_UNUSED)
}
alarm(0);
- if (virFileReadPid(abs_builddir, "commandhelper", &pid) != 0) {
+ if (virFileReadPid(abs_builddir, "commandhelper", &pid) < 0) {
printf("cannot read pidfile\n");
goto cleanup;
}
--
1.7.3.4
13 years, 4 months
[libvirt] [PATCH] Catch dnsmasq start failures
by Guido Günther
While we checked the return value we didn't maks sure ret != 0 which
resulted in dnsmasq errors being ignored.
---
src/network/bridge_driver.c | 4 +++-
1 files changed, 3 insertions(+), 1 deletions(-)
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index 554a8ac..4882753 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -731,8 +731,10 @@ networkStartDhcpDaemon(virNetworkObjPtr network)
if (ret < 0)
goto cleanup;
- if (virCommandRun(cmd, NULL) < 0)
+ ret = virCommandRun(cmd, NULL);
+ if (ret < 0) {
goto cleanup;
+ }
/*
* There really is no race here - when dnsmasq daemonizes, its
--
1.7.5.4
13 years, 4 months
[libvirt] [PATCH 1/2] SASL: Introduce session mutex
by Michal Privoznik
Some of SASL interacting functions can be called within two or more
threads with the same pointer. Therefore we need to protect
virNetSASLSessionPtr with mutex to avoid non-consistent states.
---
src/rpc/virnetsaslcontext.c | 67 +++++++++++++++++++++++++++++++++++++++++-
1 files changed, 65 insertions(+), 2 deletions(-)
diff --git a/src/rpc/virnetsaslcontext.c b/src/rpc/virnetsaslcontext.c
index 6b2a883..ef91b9d 100644
--- a/src/rpc/virnetsaslcontext.c
+++ b/src/rpc/virnetsaslcontext.c
@@ -28,6 +28,7 @@
#include "virterror_internal.h"
#include "memory.h"
#include "logging.h"
+#include "threads.h"
#define VIR_FROM_THIS VIR_FROM_RPC
#define virNetError(code, ...) \
@@ -41,6 +42,7 @@ struct _virNetSASLContext {
};
struct _virNetSASLSession {
+ virMutex lock;
sasl_conn_t *conn;
int refs;
size_t maxbufsize;
@@ -145,6 +147,16 @@ void virNetSASLContextFree(virNetSASLContextPtr ctxt)
VIR_FREE(ctxt);
}
+static void virNetSASLSessionLock(virNetSASLSessionPtr session)
+{
+ virMutexLock(&session->lock);
+}
+
+static void virNetSASLSessionUnlock(virNetSASLSessionPtr session)
+{
+ virMutexUnlock(&session->lock);
+}
+
virNetSASLSessionPtr virNetSASLSessionNewClient(virNetSASLContextPtr ctxt ATTRIBUTE_UNUSED,
const char *service,
const char *hostname,
@@ -160,6 +172,9 @@ virNetSASLSessionPtr virNetSASLSessionNewClient(virNetSASLContextPtr ctxt ATTRIB
goto cleanup;
}
+ if (virMutexInit(&sasl->lock) < 0)
+ goto cleanup;
+
sasl->refs = 1;
/* Arbitrary size for amount of data we can encode in a single block */
sasl->maxbufsize = 1 << 16;
@@ -198,6 +213,9 @@ virNetSASLSessionPtr virNetSASLSessionNewServer(virNetSASLContextPtr ctxt ATTRIB
goto cleanup;
}
+ if (virMutexInit(&sasl->lock) < 0)
+ goto cleanup;
+
sasl->refs = 1;
/* Arbitrary size for amount of data we can encode in a single block */
sasl->maxbufsize = 1 << 16;
@@ -226,7 +244,9 @@ cleanup:
void virNetSASLSessionRef(virNetSASLSessionPtr sasl)
{
+ virNetSASLSessionLock(sasl);
sasl->refs++;
+ virNetSASLSessionUnlock(sasl);
}
int virNetSASLSessionExtKeySize(virNetSASLSessionPtr sasl,
@@ -234,13 +254,16 @@ int virNetSASLSessionExtKeySize(virNetSASLSessionPtr sasl,
{
int err;
+ virNetSASLSessionLock(sasl);
err = sasl_setprop(sasl->conn, SASL_SSF_EXTERNAL, &ssf);
if (err != SASL_OK) {
virNetError(VIR_ERR_INTERNAL_ERROR,
_("cannot set external SSF %d (%s)"),
err, sasl_errstring(err, NULL, NULL));
+ virNetSASLSessionUnlock(sasl);
return -1;
}
+ virNetSASLSessionUnlock(sasl);
return 0;
}
@@ -249,13 +272,16 @@ const char *virNetSASLSessionGetIdentity(virNetSASLSessionPtr sasl)
const void *val;
int err;
+ virNetSASLSessionLock(sasl);
err = sasl_getprop(sasl->conn, SASL_USERNAME, &val);
if (err != SASL_OK) {
virNetError(VIR_ERR_AUTH_FAILED,
_("cannot query SASL username on connection %d (%s)"),
err, sasl_errstring(err, NULL, NULL));
+ virNetSASLSessionUnlock(sasl);
return NULL;
}
+ virNetSASLSessionUnlock(sasl);
if (val == NULL) {
virNetError(VIR_ERR_AUTH_FAILED,
_("no client username was found"));
@@ -272,13 +298,17 @@ int virNetSASLSessionGetKeySize(virNetSASLSessionPtr sasl)
int err;
int ssf;
const void *val;
+
+ virNetSASLSessionLock(sasl);
err = sasl_getprop(sasl->conn, SASL_SSF, &val);
if (err != SASL_OK) {
virNetError(VIR_ERR_AUTH_FAILED,
_("cannot query SASL ssf on connection %d (%s)"),
err, sasl_errstring(err, NULL, NULL));
+ virNetSASLSessionUnlock(sasl);
return -1;
}
+ virNetSASLSessionUnlock(sasl);
ssf = *(const int *)val;
return ssf;
}
@@ -291,6 +321,7 @@ int virNetSASLSessionSecProps(virNetSASLSessionPtr sasl,
sasl_security_properties_t secprops;
int err;
+ virNetSASLSessionLock(sasl);
VIR_DEBUG("minSSF=%d maxSSF=%d allowAnonymous=%d maxbufsize=%zu",
minSSF, maxSSF, allowAnonymous, sasl->maxbufsize);
@@ -307,8 +338,10 @@ int virNetSASLSessionSecProps(virNetSASLSessionPtr sasl,
virNetError(VIR_ERR_INTERNAL_ERROR,
_("cannot set security props %d (%s)"),
err, sasl_errstring(err, NULL, NULL));
+ virNetSASLSessionUnlock(sasl);
return -1;
}
+ virNetSASLSessionUnlock(sasl);
return 0;
}
@@ -319,17 +352,20 @@ static int virNetSASLSessionUpdateBufSize(virNetSASLSessionPtr sasl)
unsigned *maxbufsize;
int err;
+ virNetSASLSessionLock(sasl);
err = sasl_getprop(sasl->conn, SASL_MAXOUTBUF, (const void **)&maxbufsize);
if (err != SASL_OK) {
virNetError(VIR_ERR_INTERNAL_ERROR,
_("cannot get security props %d (%s)"),
err, sasl_errstring(err, NULL, NULL));
+ virNetSASLSessionUnlock(sasl);
return -1;
}
VIR_DEBUG("Negotiated bufsize is %u vs requested size %zu",
*maxbufsize, sasl->maxbufsize);
sasl->maxbufsize = *maxbufsize;
+ virNetSASLSessionUnlock(sasl);
return 0;
}
@@ -339,6 +375,7 @@ char *virNetSASLSessionListMechanisms(virNetSASLSessionPtr sasl)
char *ret;
int err;
+ virNetSASLSessionLock(sasl);
err = sasl_listmech(sasl->conn,
NULL, /* Don't need to set user */
"", /* Prefix */
@@ -351,8 +388,10 @@ char *virNetSASLSessionListMechanisms(virNetSASLSessionPtr sasl)
virNetError(VIR_ERR_INTERNAL_ERROR,
_("cannot list SASL mechanisms %d (%s)"),
err, sasl_errdetail(sasl->conn));
+ virNetSASLSessionUnlock(sasl);
return NULL;
}
+ virNetSASLSessionUnlock(sasl);
if (!(ret = strdup(mechlist))) {
virReportOOMError();
return NULL;
@@ -373,6 +412,7 @@ int virNetSASLSessionClientStart(virNetSASLSessionPtr sasl,
VIR_DEBUG("sasl=%p mechlist=%s prompt_need=%p clientout=%p clientoutlen=%p mech=%p",
sasl, mechlist, prompt_need, clientout, clientoutlen, mech);
+ virNetSASLSessionLock(sasl);
int err = sasl_client_start(sasl->conn,
mechlist,
prompt_need,
@@ -380,6 +420,7 @@ int virNetSASLSessionClientStart(virNetSASLSessionPtr sasl,
&outlen,
mech);
+ virNetSASLSessionUnlock(sasl);
*clientoutlen = outlen;
switch (err) {
@@ -414,12 +455,14 @@ int virNetSASLSessionClientStep(virNetSASLSessionPtr sasl,
VIR_DEBUG("sasl=%p serverin=%s serverinlen=%zu prompt_need=%p clientout=%p clientoutlen=%p",
sasl, serverin, serverinlen, prompt_need, clientout, clientoutlen);
+ virNetSASLSessionLock(sasl);
int err = sasl_client_step(sasl->conn,
serverin,
inlen,
prompt_need,
clientout,
&outlen);
+ virNetSASLSessionUnlock(sasl);
*clientoutlen = outlen;
switch (err) {
@@ -449,6 +492,8 @@ int virNetSASLSessionServerStart(virNetSASLSessionPtr sasl,
{
unsigned inlen = clientinlen;
unsigned outlen = 0;
+
+ virNetSASLSessionLock(sasl);
int err = sasl_server_start(sasl->conn,
mechname,
clientin,
@@ -456,6 +501,7 @@ int virNetSASLSessionServerStart(virNetSASLSessionPtr sasl,
serverout,
&outlen);
+ virNetSASLSessionUnlock(sasl);
*serveroutlen = outlen;
switch (err) {
@@ -486,12 +532,14 @@ int virNetSASLSessionServerStep(virNetSASLSessionPtr sasl,
unsigned inlen = clientinlen;
unsigned outlen = 0;
+ virNetSASLSessionLock(sasl);
int err = sasl_server_step(sasl->conn,
clientin,
inlen,
serverout,
&outlen);
+ virNetSASLSessionUnlock(sasl);
*serveroutlen = outlen;
switch (err) {
@@ -514,7 +562,11 @@ int virNetSASLSessionServerStep(virNetSASLSessionPtr sasl,
size_t virNetSASLSessionGetMaxBufSize(virNetSASLSessionPtr sasl)
{
- return sasl->maxbufsize;
+ size_t ret;
+ virNetSASLSessionLock(sasl);
+ ret = sasl->maxbufsize;
+ virNetSASLSessionUnlock(sasl);
+ return ret;
}
ssize_t virNetSASLSessionEncode(virNetSASLSessionPtr sasl,
@@ -534,6 +586,7 @@ ssize_t virNetSASLSessionEncode(virNetSASLSessionPtr sasl,
return -1;
}
+ virNetSASLSessionLock(sasl);
err = sasl_encode(sasl->conn,
input,
inlen,
@@ -545,8 +598,10 @@ ssize_t virNetSASLSessionEncode(virNetSASLSessionPtr sasl,
virNetError(VIR_ERR_INTERNAL_ERROR,
_("failed to encode SASL data: %d (%s)"),
err, sasl_errstring(err, NULL, NULL));
+ virNetSASLSessionUnlock(sasl);
return -1;
}
+ virNetSASLSessionUnlock(sasl);
return 0;
}
@@ -567,6 +622,7 @@ ssize_t virNetSASLSessionDecode(virNetSASLSessionPtr sasl,
return -1;
}
+ virNetSASLSessionLock(sasl);
err = sasl_decode(sasl->conn,
input,
inlen,
@@ -577,8 +633,10 @@ ssize_t virNetSASLSessionDecode(virNetSASLSessionPtr sasl,
virNetError(VIR_ERR_INTERNAL_ERROR,
_("failed to decode SASL data: %d (%s)"),
err, sasl_errstring(err, NULL, NULL));
+ virNetSASLSessionUnlock(sasl);
return -1;
}
+ virNetSASLSessionUnlock(sasl);
return 0;
}
@@ -587,12 +645,17 @@ void virNetSASLSessionFree(virNetSASLSessionPtr sasl)
if (!sasl)
return;
+ virNetSASLSessionLock(sasl);
sasl->refs--;
- if (sasl->refs > 0)
+ if (sasl->refs > 0) {
+ virNetSASLSessionUnlock(sasl);
return;
+ }
if (sasl->conn)
sasl_dispose(&sasl->conn);
+ virNetSASLSessionUnlock(sasl);
+ virMutexDestroy(&sasl->lock);
VIR_FREE(sasl);
}
--
1.7.5.rc3
13 years, 4 months
[libvirt] [PATCH] Add libtasn1-devel as a BuildRequires for libvirt.spec
by Daniel P. Berrange
* libvirt.spec.in: Add libtasn1-devel
---
libvirt.spec.in | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/libvirt.spec.in b/libvirt.spec.in
index 002239c..e2b7f65 100644
--- a/libvirt.spec.in
+++ b/libvirt.spec.in
@@ -332,6 +332,7 @@ BuildRequires: libxslt
BuildRequires: readline-devel
BuildRequires: ncurses-devel
BuildRequires: gettext
+BuildRequires: libtasn1-devel
BuildRequires: gnutls-devel
%if 0%{?fedora} >= 12 || 0%{?rhel} >= 6
# for augparse, optionally used in testing
--
1.7.1
13 years, 4 months