[libvirt] [RFC PATCH 0/4] powerpc : Libvirt for the PowerPC platform
by Prerna Saxena
Recent development in KVM for 64-bit Power ISA Book3S machines, allows
users to run multiple KVM guest instances on POWER7 and PPC970
processor based systems. Also qemu-system-ppc64 has been enhanced to
support a new machine type "pseries" suitable for Power Book3S machines.
This addition effectively brings the KVM+qemu combination to run
multiple guest instances on a Power Book3S machine.
Libvirt continues to be the key interface to configure and manage the
KVM guest instances on x86. We would like to enhance libvirt to
support KVM guest configuration and management on Power Book3S
machines.
The following set of patches tries to illustrate the porting issues in
libvirt since it has been predominantly designed and used for x86 KVM.
I would like to discuss these issues and list out the possibilities of
refactoring the code and make it easier for adding support for non-x86
architectures.
Some of the key changes that would be needed in libvirt to manage
guests on qemu-system-ppc64 'pseries' platform would be as follows:
1) A new driver would be needed for PowerPC CPU, to identify and filter
supported PowerPC-CPU families.
2) A new set of interfaces would be needed to extract host system and
firmware information (SMBIOS and host-OS information like CPU and
memory topology, processor type, hardware threads, etc).
3) Clean abstraction of platform-specific references such as ACPI
dependencies from generic domain initialization sequence. (Many
such options get automatically selected by libvirt, unless they are
explicitly flagged as unrequired in XML. This default list will
differ for every architecture).
4) A mechanism to specify the list of allowable devices for every
architecture -- the 'pseries' vm would boot with its own set of
devices, some of which may not be available with x86.
In order to address the above requirements, we could take one of the
following implementation schemes:
Approach 1:
-----------
Create a new host backend for powerpc-kvm -- similar to xen, kvm, esx,
etc.
Advantage :
Even if the qemu device model on ppc varies significantly, the
difference between the device model between qemu-system-ppc64 and
qemu-system-x86_64 can be easily managed.
It could possibly allow easier ways of segregating supported devices,
and also specifying a new set of methods to gather host system
information.
Drawback:
- Overhead of maintaining a new backend, which is expected to have
some similarities with the x86-specific 'KVM' backend.
- Might get confusing for end users.
Approach 2:
-----------
Hack the present 'kvm' backend to add powerpc-specific features.
Advantage:
Having a seamless 'kvm' interface across architectures would be of
more convenience to the end-user -- a single XML spec could work
with only a small subset of arch-specific changes. Also, newer
features that come in for one arch would be more easily ported to
others. However, it would entail more run-time switches based on
the host kvm architecture.
One way to do this would be to add a new arch-specific layer within
the 'kvm' backend. This would be compiled-in depending on the host
architecture, and would expose only those features (system
information, devices, features etc) which are implemented in kvm
_on_that_platform_.
Drawback:
This will cause some rewriting of how internal qemu/kvm interfaces
interact in libvirt.
The attached patch series (albeit hackish in nature) attempts to
illustrate the difference in the architecture and call out parts of the
libvirt code that would need changes.
--
Prerna Saxena
Linux Technology Centre,
IBM Systems and Technology Lab,
Bangalore, India
13 years, 6 months
[libvirt] [PATCH] build: add compiler attributes to virUUIDParse
by Eric Blake
Coverity complained that most, but not all, clients of virUUIDParse
were checking for errors. Silence those coverity warnings by
explicitly marking the cases where we trust the input, and fixing
one instance that really should have been checking. In particular,
this silences about half of the 46 warnings I saw on my most
recent Coverity analysis run.
* src/util/uuid.h (virUUIDParse): Enforce rules.
* src/util/uuid.c (virUUIDParse): Drop impossible check; at least
Coverity will detect if we break rules and pass NULL.
* src/xenapi/xenapi_driver.c (xenapiDomainCreateXML)
(xenapiDomainLookupByID, xenapiDomainLookupByName)
(xenapiDomainDefineXML): Ignore return when we trust data source.
* src/vbox/vbox_tmpl.c (nsIDtoChar, vboxIIDToUUID_v3_x)
(vboxCallbackOnMachineStateChange)
(vboxCallbackOnMachineRegistered, vboxStoragePoolLookupByName):
Likewise.
* src/node_device/node_device_hal.c (gather_system_cap): Likewise.
* src/xenxs/xen_sxpr.c (xenParseSxpr): Check for errors.
---
This one's big enough that I'll wait for ACK before pushing.
src/node_device/node_device_hal.c | 3 ++-
src/util/uuid.c | 5 +----
src/util/uuid.h | 3 ++-
src/vbox/vbox_tmpl.c | 12 ++++++------
src/xenapi/xenapi_driver.c | 11 ++++++-----
src/xenxs/xen_sxpr.c | 3 ++-
6 files changed, 19 insertions(+), 18 deletions(-)
diff --git a/src/node_device/node_device_hal.c b/src/node_device/node_device_hal.c
index 481be97..a028886 100644
--- a/src/node_device/node_device_hal.c
+++ b/src/node_device/node_device_hal.c
@@ -38,6 +38,7 @@
#include "pci.h"
#include "logging.h"
#include "node_device_driver.h"
+#include "ignore-value.h"
#define VIR_FROM_THIS VIR_FROM_NODEDEV
@@ -299,7 +300,7 @@ static int gather_system_cap(LibHalContext *ctx, const char *udi,
(void)get_str_prop(ctx, udi, "system.hardware.serial",
&d->system.hardware.serial);
if (get_str_prop(ctx, udi, "system.hardware.uuid", &uuidstr) == 0) {
- (void)virUUIDParse(uuidstr, d->system.hardware.uuid);
+ ignore_value(virUUIDParse(uuidstr, d->system.hardware.uuid));
VIR_FREE(uuidstr);
}
(void)get_str_prop(ctx, udi, "system.firmware.vendor",
diff --git a/src/util/uuid.c b/src/util/uuid.c
index b4317df..0df3ebc 100644
--- a/src/util/uuid.c
+++ b/src/util/uuid.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007, 2008, 2009, 2010 Red Hat, Inc.
+ * Copyright (C) 2007-2011 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -129,9 +129,6 @@ virUUIDParse(const char *uuidstr, unsigned char *uuid) {
const char *cur;
int i;
- if ((uuidstr == NULL) || (uuid == NULL))
- return(-1);
-
/*
* do a liberal scan allowing '-' and ' ' anywhere between character
* pairs, and surrounding whitespace, as long as there are exactly
diff --git a/src/util/uuid.h b/src/util/uuid.h
index b5d7878..7dbfad5 100644
--- a/src/util/uuid.h
+++ b/src/util/uuid.h
@@ -32,7 +32,8 @@ int virUUIDIsValid(unsigned char *uuid);
int virUUIDGenerate(unsigned char *uuid);
int virUUIDParse(const char *uuidstr,
- unsigned char *uuid);
+ unsigned char *uuid)
+ ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK;
void virUUIDFormat(const unsigned char *uuid,
char *uuidstr) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c
index 9b674a9..bc19b63 100644
--- a/src/vbox/vbox_tmpl.c
+++ b/src/vbox/vbox_tmpl.c
@@ -300,7 +300,7 @@ static void nsIDtoChar(unsigned char *uuid, const nsID *iid) {
}
uuidstrdst[VIR_UUID_STRING_BUFLEN-1] = '\0';
- virUUIDParse(uuidstrdst, uuid);
+ ignore_value(virUUIDParse(uuidstrdst, uuid));
}
static void nsIDFromChar(nsID *iid, const unsigned char *uuid) {
@@ -339,7 +339,7 @@ static void nsIDFromChar(nsID *iid, const unsigned char *uuid) {
}
uuidstrdst[VIR_UUID_STRING_BUFLEN-1] = '\0';
- virUUIDParse(uuidstrdst, uuidinterim);
+ ignore_value(virUUIDParse(uuidstrdst, uuidinterim));
memcpy(iid, uuidinterim, VIR_UUID_BUFLEN);
}
@@ -511,7 +511,7 @@ vboxIIDToUUID_v3_x(vboxGlobalData *data, vboxIID_v3_x *iid,
data->pFuncs->pfnUtf16ToUtf8(iid->value, &utf8);
- virUUIDParse(utf8, uuid);
+ ignore_value(virUUIDParse(utf8, uuid));
data->pFuncs->pfnUtf8Free(utf8);
}
@@ -6558,7 +6558,7 @@ vboxCallbackOnMachineStateChange(IVirtualBoxCallback *pThis ATTRIBUTE_UNUSED,
unsigned char uuid[VIR_UUID_BUFLEN];
g_pVBoxGlobalData->pFuncs->pfnUtf16ToUtf8(machineId, &machineIdUtf8);
- virUUIDParse(machineIdUtf8, uuid);
+ ignore_value(virUUIDParse(machineIdUtf8, uuid));
dom = vboxDomainLookupByUUID(g_pVBoxGlobalData->conn, uuid);
if (dom) {
@@ -6686,7 +6686,7 @@ vboxCallbackOnMachineRegistered(IVirtualBoxCallback *pThis ATTRIBUTE_UNUSED,
unsigned char uuid[VIR_UUID_BUFLEN];
g_pVBoxGlobalData->pFuncs->pfnUtf16ToUtf8(machineId, &machineIdUtf8);
- virUUIDParse(machineIdUtf8, uuid);
+ ignore_value(virUUIDParse(machineIdUtf8, uuid));
dom = vboxDomainLookupByUUID(g_pVBoxGlobalData->conn, uuid);
if (dom) {
@@ -7983,7 +7983,7 @@ static virStoragePoolPtr vboxStoragePoolLookupByName(virConnectPtr conn, const c
unsigned char uuid[VIR_UUID_BUFLEN];
const char *uuidstr = "1deff1ff-1481-464f-967f-a50fe8936cc4";
- virUUIDParse(uuidstr, uuid);
+ ignore_value(virUUIDParse(uuidstr, uuid));
ret = virGetStoragePool(conn, name, uuid);
}
diff --git a/src/xenapi/xenapi_driver.c b/src/xenapi/xenapi_driver.c
index 80a706a..3946455 100644
--- a/src/xenapi/xenapi_driver.c
+++ b/src/xenapi/xenapi_driver.c
@@ -40,6 +40,7 @@
#include "xenapi_driver.h"
#include "xenapi_driver_private.h"
#include "xenapi_utils.h"
+#include "ignore-value.h"
#define VIR_FROM_THIS VIR_FROM_XENAPI
@@ -528,7 +529,7 @@ xenapiDomainCreateXML (virConnectPtr conn,
virDomainDefFree(defPtr);
if (record) {
unsigned char raw_uuid[VIR_UUID_BUFLEN];
- virUUIDParse(record->uuid, raw_uuid);
+ ignore_value(virUUIDParse(record->uuid, raw_uuid));
if (vm) {
if (xen_vm_start(session, vm, false, false)) {
domP = virGetDomain(conn, record->name_label, raw_uuid);
@@ -574,13 +575,13 @@ xenapiDomainLookupByID (virConnectPtr conn, int id)
xen_session_get_this_host(session, &host, session);
if (host != NULL && session->ok) {
xen_host_get_resident_vms(session, &result, host);
- if (result != NULL ) {
+ if (result != NULL) {
for (i = 0; i < result->size; i++) {
xen_vm_get_domid(session, &domID, result->contents[i]);
if (domID == id) {
xen_vm_get_record(session, &record, result->contents[i]);
xen_vm_get_uuid(session, &uuid, result->contents[i]);
- virUUIDParse(uuid, raw_uuid);
+ ignore_value(virUUIDParse(uuid, raw_uuid));
domP = virGetDomain(conn, record->name_label, raw_uuid);
if (domP) {
int64_t domid = -1;
@@ -672,7 +673,7 @@ xenapiDomainLookupByName (virConnectPtr conn,
vm = vms->contents[0];
xen_vm_get_uuid(session, &uuid, vm);
if (uuid!=NULL) {
- virUUIDParse(uuid, raw_uuid);
+ ignore_value(virUUIDParse(uuid, raw_uuid));
domP = virGetDomain(conn, name, raw_uuid);
if (domP != NULL) {
int64_t domid = -1;
@@ -1683,7 +1684,7 @@ xenapiDomainDefineXML (virConnectPtr conn, const char *xml)
}
if (record != NULL) {
unsigned char raw_uuid[VIR_UUID_BUFLEN];
- virUUIDParse(record->uuid, raw_uuid);
+ ignore_value(virUUIDParse(record->uuid, raw_uuid));
domP = virGetDomain(conn, record->name_label, raw_uuid);
if (!domP && !session->ok)
xenapiSessionErrorHandler(conn, VIR_ERR_NO_DOMAIN, NULL);
diff --git a/src/xenxs/xen_sxpr.c b/src/xenxs/xen_sxpr.c
index f2447f7..d44b0dc 100644
--- a/src/xenxs/xen_sxpr.c
+++ b/src/xenxs/xen_sxpr.c
@@ -1094,7 +1094,8 @@ xenParseSxpr(const struct sexpr *root,
"%s", _("domain information incomplete, missing name"));
goto error;
}
- virUUIDParse(tmp, def->uuid);
+ if (virUUIDParse(tmp, def->uuid) < 0)
+ goto error;
if (sexpr_node_copy(root, "domain/description", &def->description) < 0)
goto no_memory;
--
1.7.4.4
13 years, 6 months
[libvirt] [PATCH] qemu: plug memory leak on migration
by Eric Blake
Detected by Coverity. Leak introduced in commit 72de0d2.
* src/qemu/qemu_migration.c (qemuMigrationCookieGraphicsXMLParse):
Clean up on success.
---
Pushing under the trivial rule.
src/qemu/qemu_migration.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 4516231..f0a0e49 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -460,22 +460,23 @@ qemuMigrationCookieGraphicsXMLParse(xmlXPathContextPtr ctxt)
if (!(tmp = virXPathString("string(./graphics/@type)", ctxt))) {
qemuReportError(VIR_ERR_INTERNAL_ERROR,
"%s", _("missing type attribute in migration data"));
goto error;
}
if ((grap->type = virDomainGraphicsTypeFromString(tmp)) < 0) {
qemuReportError(VIR_ERR_INTERNAL_ERROR,
_("unknown graphics type %s"), tmp);
VIR_FREE(tmp);
goto error;
}
+ VIR_FREE(tmp);
if (virXPathInt("string(./graphics/@port)", ctxt, &grap->port) < 0) {
qemuReportError(VIR_ERR_INTERNAL_ERROR,
"%s", _("missing port attribute in migration data"));
goto error;
}
if (grap->type == VIR_DOMAIN_GRAPHICS_TYPE_SPICE) {
if (virXPathInt("string(./graphics/@tlsPort)", ctxt, &grap->tlsPort) < 0) {
qemuReportError(VIR_ERR_INTERNAL_ERROR,
"%s", _("missing tlsPort attribute in migration data"));
goto error;
}
--
1.7.4.4
13 years, 6 months
[libvirt] [PATCH] conf: plug memory leak on error
by Eric Blake
Detected by Coverity. Leak present since commit 874e65a; and
while commit d50bb45 tried to fix the issue, it missed a path.
* src/conf/domain_conf.c (virDomainDefParseBootXML): Always clean
up useserial.
---
Pushing under the trivial rule.
src/conf/domain_conf.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 8cd493b..844af27 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -6316,35 +6316,35 @@ virDomainDefParseBootXML(xmlXPathContextPtr ctxt,
useserial = virXPathString("string(./os/bios[1]/@useserial)", ctxt);
if (useserial) {
if (STREQ(useserial, "yes")) {
if (virXPathULong("count(./devices/serial)",
ctxt, &serialPorts) < 0) {
virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("need at least one serial port "
"for useserial"));
goto cleanup;
}
def->os.bios.useserial = VIR_DOMAIN_BIOS_USESERIAL_YES;
} else {
def->os.bios.useserial = VIR_DOMAIN_BIOS_USESERIAL_NO;
}
- VIR_FREE(useserial);
}
*bootCount = deviceBoot;
ret = 0;
cleanup:
+ VIR_FREE(useserial);
VIR_FREE(nodes);
return ret;
}
/* Parse the XML definition for a vcpupin */
static virDomainVcpuPinDefPtr
virDomainVcpuPinDefParseXML(const xmlNodePtr node,
xmlXPathContextPtr ctxt,
int maxvcpus)
{
virDomainVcpuPinDefPtr def;
xmlNodePtr oldnode = ctxt->node;
unsigned int vcpuid;
char *tmp = NULL;
--
1.7.4.4
13 years, 6 months
[libvirt] [PATCH 2/3] Add virBufferEscapeShell
by Guido Günther
Escape strings so they're safe to pass to the shell. Based on glib's
g_quote_string.
---
src/libvirt_private.syms | 1 +
src/util/buf.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++
src/util/buf.h | 1 +
3 files changed, 56 insertions(+), 0 deletions(-)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 4f96518..862f3ac 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -29,6 +29,7 @@ virBufferEscape;
virBufferEscapeSexpr;
virBufferEscapeString;
virBufferFreeAndReset;
+virBufferEscapeShell;
virBufferStrcat;
virBufferURIEncodeString;
virBufferUse;
diff --git a/src/util/buf.c b/src/util/buf.c
index fa12855..f9d7cd7 100644
--- a/src/util/buf.c
+++ b/src/util/buf.c
@@ -486,6 +486,60 @@ virBufferURIEncodeString (virBufferPtr buf, const char *str)
}
/**
+ * virBufferEscapeShell:
+ * @buf: the buffer to append to
+ * @str: an unquoted string
+ *
+ * Quotes a string so that the shell (/bin/sh) will interpret the
+ * quoted string as unquoted_string.
+ */
+void
+virBufferEscapeShell(const virBufferPtr buf, const char *str)
+{
+ int len;
+ bool close_quote = false;
+ char *escaped, *out;
+ const char *cur;
+
+ if ((buf == NULL) || (str == NULL))
+ return;
+
+ if (buf->error)
+ return;
+
+ len = strlen(str);
+ if (xalloc_oversized(4, len) ||
+ VIR_ALLOC_N(escaped, 4 * len + 3) < 0) {
+ virBufferSetError(buf);
+ return;
+ }
+
+ cur = str;
+ out = escaped;
+
+ /* Add outer '...' only if arg included shell metacharacters. */
+ if (strpbrk(str, "\r\t\n !\"#$&'()*;<>?[\\]^`{|}~")) {
+ *out++ = '\'';
+ close_quote = true;
+ }
+ while (*cur != 0) {
+ if (*cur == '\'') {
+ /* Replace literal ' with a close ', a \', and a open ' */
+ *out++ = '\'';
+ *out++ = '\\';
+ *out++ = *cur++;
+ *out++ = '\'';
+ } else
+ *out++ = *cur++;
+ }
+ if (close_quote)
+ *out++ = '\'';
+ *out = 0;
+ virBufferAdd(buf, escaped, -1);
+ VIR_FREE(escaped);
+}
+
+/**
* virBufferStrcat:
* @buf: the buffer to dump
* @...: the variable list of strings, the last argument must be NULL
diff --git a/src/util/buf.h b/src/util/buf.h
index e545ed9..ad8ef86 100644
--- a/src/util/buf.h
+++ b/src/util/buf.h
@@ -52,6 +52,7 @@ void virBufferEscapeString(const virBufferPtr buf, const char *format, const cha
void virBufferEscapeSexpr(const virBufferPtr buf, const char *format, const char *str);
void virBufferEscape(const virBufferPtr buf, const char *toescape, const char *format, const char *str);
void virBufferURIEncodeString (const virBufferPtr buf, const char *str);
+void virBufferEscapeShell(const virBufferPtr buf, const char *str);
# define virBufferAddLit(buf_, literal_string_) \
virBufferAdd (buf_, "" literal_string_ "", sizeof literal_string_ - 1)
--
1.7.6.3
13 years, 6 months
[libvirt] [PATCH 3/3] Use virBufferEscapeShell in virNetSocketNewConnectSSH
by Guido Günther
to escape the netcat command since it's passed to the shell. Adjust
expected test case output accordingly.
---
src/rpc/virnetsocket.c | 25 ++++++++++++++++++++-----
tests/virnetsockettest.c | 10 +++++-----
2 files changed, 25 insertions(+), 10 deletions(-)
diff --git a/src/rpc/virnetsocket.c b/src/rpc/virnetsocket.c
index ea653da..0105e45 100644
--- a/src/rpc/virnetsocket.c
+++ b/src/rpc/virnetsocket.c
@@ -612,7 +612,10 @@ int virNetSocketNewConnectSSH(const char *nodename,
const char *path,
virNetSocketPtr *retsock)
{
+ char *quoted;
virCommandPtr cmd;
+ virBuffer buf = VIR_BUFFER_INITIALIZER;
+
*retsock = NULL;
cmd = virCommandNew(binary ? binary : "ssh");
@@ -636,6 +639,19 @@ int virNetSocketNewConnectSSH(const char *nodename,
virCommandAddArgList(cmd, "-o", "StrictHostKeyChecking=no", NULL);
virCommandAddArgList(cmd, nodename, "sh", "-c", NULL);
+
+ virBufferEscapeShell(&buf, netcat ? netcat : "nc");
+ if (virBufferError(&buf)) {
+ virBufferFreeAndReset(&buf);
+ virReportOOMError();
+ return -1;
+ }
+ quoted = virBufferContentAndReset(&buf);
+ if (quoted == NULL) {
+ virReportOOMError();
+ return -1;
+ }
+
/*
* This ugly thing is a shell script to detect availability of
* the -q option for 'nc': debian and suse based distros need this
@@ -647,14 +663,13 @@ int virNetSocketNewConnectSSH(const char *nodename,
* behavior.
*/
virCommandAddArgFormat(cmd,
- "'if %s -q 2>&1 | grep \"requires an argument\" >/dev/null 2>&1; then"
+ "'if '%s' -q 2>&1 | grep \"requires an argument\" >/dev/null 2>&1; then"
" ARG=-q0;"
"fi;"
- "%s $ARG -U %s'",
- netcat ? netcat : "nc",
- netcat ? netcat : "nc",
- path);
+ "'%s' $ARG -U %s'",
+ quoted, quoted, path);
+ VIR_FREE(quoted);
return virNetSocketNewConnectCommand(cmd, retsock);
}
diff --git a/tests/virnetsockettest.c b/tests/virnetsockettest.c
index b3a2705..c063e74 100644
--- a/tests/virnetsockettest.c
+++ b/tests/virnetsockettest.c
@@ -496,7 +496,7 @@ mymain(void)
struct testSSHData sshData1 = {
.nodename = "somehost",
.path = "/tmp/socket",
- .expectOut = "somehost sh -c 'if nc -q 2>&1 | grep \"requires an argument\" >/dev/null 2>&1; then ARG=-q0;fi;nc $ARG -U /tmp/socket'\n",
+ .expectOut = "somehost sh -c 'if 'nc' -q 2>&1 | grep \"requires an argument\" >/dev/null 2>&1; then ARG=-q0;fi;'nc' $ARG -U /tmp/socket'\n",
};
if (virtTestRun("SSH test 1", 1, testSocketSSH, &sshData1) < 0)
ret = -1;
@@ -509,7 +509,7 @@ mymain(void)
.noTTY = true,
.noVerify = false,
.path = "/tmp/socket",
- .expectOut = "-p 9000 -l fred -T -o BatchMode=yes -e none somehost sh -c 'if netcat -q 2>&1 | grep \"requires an argument\" >/dev/null 2>&1; then ARG=-q0;fi;netcat $ARG -U /tmp/socket'\n",
+ .expectOut = "-p 9000 -l fred -T -o BatchMode=yes -e none somehost sh -c 'if 'netcat' -q 2>&1 | grep \"requires an argument\" >/dev/null 2>&1; then ARG=-q0;fi;'netcat' $ARG -U /tmp/socket'\n",
};
if (virtTestRun("SSH test 2", 1, testSocketSSH, &sshData2) < 0)
ret = -1;
@@ -522,7 +522,7 @@ mymain(void)
.noTTY = false,
.noVerify = true,
.path = "/tmp/socket",
- .expectOut = "-p 9000 -l fred -o StrictHostKeyChecking=no somehost sh -c 'if netcat -q 2>&1 | grep \"requires an argument\" >/dev/null 2>&1; then ARG=-q0;fi;netcat $ARG -U /tmp/socket'\n",
+ .expectOut = "-p 9000 -l fred -o StrictHostKeyChecking=no somehost sh -c 'if 'netcat' -q 2>&1 | grep \"requires an argument\" >/dev/null 2>&1; then ARG=-q0;fi;'netcat' $ARG -U /tmp/socket'\n",
};
if (virtTestRun("SSH test 3", 1, testSocketSSH, &sshData3) < 0)
ret = -1;
@@ -538,7 +538,7 @@ mymain(void)
struct testSSHData sshData5 = {
.nodename = "crashyhost",
.path = "/tmp/socket",
- .expectOut = "crashyhost sh -c 'if nc -q 2>&1 | grep \"requires an argument\" >/dev/null 2>&1; then ARG=-q0;fi;nc $ARG -U /tmp/socket'\n",
+ .expectOut = "crashyhost sh -c 'if 'nc' -q 2>&1 | grep \"requires an argument\" >/dev/null 2>&1; then ARG=-q0;fi;'nc' $ARG -U /tmp/socket'\n",
.dieEarly = true,
};
@@ -550,7 +550,7 @@ mymain(void)
.path = "/tmp/socket",
.keyfile = "/root/.ssh/example_key",
.noVerify = true,
- .expectOut = "-i /root/.ssh/example_key -o StrictHostKeyChecking=no example.com sh -c 'if nc -q 2>&1 | grep \"requires an argument\" >/dev/null 2>&1; then ARG=-q0;fi;nc $ARG -U /tmp/socket'\n",
+ .expectOut = "-i /root/.ssh/example_key -o StrictHostKeyChecking=no example.com sh -c 'if 'nc' -q 2>&1 | grep \"requires an argument\" >/dev/null 2>&1; then ARG=-q0;fi;'nc' $ARG -U /tmp/socket'\n",
};
if (virtTestRun("SSH test 6", 1, testSocketSSH, &sshData6) < 0)
ret = -1;
--
1.7.6.3
13 years, 6 months
[libvirt] [PATCH 1/3] Autodetect if the remote nc command supports the -q option
by Guido Günther
Based on a patch by Marc Deslauriers <marc.deslauriers(a)ubuntu.com>
RH: https://bugzilla.redhat.com/show_bug.cgi?id=562176
Ubuntu: https://bugs.launchpad.net/ubuntu/+source/libvirt/+bug/517478
Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=573172
---
src/rpc/virnetsocket.c | 23 ++++++++++++++++++++---
tests/virnetsockettest.c | 11 ++++++-----
2 files changed, 26 insertions(+), 8 deletions(-)
diff --git a/src/rpc/virnetsocket.c b/src/rpc/virnetsocket.c
index e4289b1..ea653da 100644
--- a/src/rpc/virnetsocket.c
+++ b/src/rpc/virnetsocket.c
@@ -634,9 +634,26 @@ int virNetSocketNewConnectSSH(const char *nodename,
"-e", "none", NULL);
if (noVerify)
virCommandAddArgList(cmd, "-o", "StrictHostKeyChecking=no", NULL);
- virCommandAddArgList(cmd, nodename,
- netcat ? netcat : "nc",
- "-U", path, NULL);
+
+ virCommandAddArgList(cmd, nodename, "sh", "-c", NULL);
+ /*
+ * This ugly thing is a shell script to detect availability of
+ * the -q option for 'nc': debian and suse based distros need this
+ * flag to ensure the remote nc will exit on EOF, so it will go away
+ * when we close the connection tunnel. If it doesn't go away, subsequent
+ * connection attempts will hang.
+ *
+ * Fedora's 'nc' doesn't have this option, and defaults to the desired
+ * behavior.
+ */
+ virCommandAddArgFormat(cmd,
+ "'if %s -q 2>&1 | grep \"requires an argument\" >/dev/null 2>&1; then"
+ " ARG=-q0;"
+ "fi;"
+ "%s $ARG -U %s'",
+ netcat ? netcat : "nc",
+ netcat ? netcat : "nc",
+ path);
return virNetSocketNewConnectCommand(cmd, retsock);
}
diff --git a/tests/virnetsockettest.c b/tests/virnetsockettest.c
index fae15a3..b3a2705 100644
--- a/tests/virnetsockettest.c
+++ b/tests/virnetsockettest.c
@@ -496,7 +496,7 @@ mymain(void)
struct testSSHData sshData1 = {
.nodename = "somehost",
.path = "/tmp/socket",
- .expectOut = "somehost nc -U /tmp/socket\n",
+ .expectOut = "somehost sh -c 'if nc -q 2>&1 | grep \"requires an argument\" >/dev/null 2>&1; then ARG=-q0;fi;nc $ARG -U /tmp/socket'\n",
};
if (virtTestRun("SSH test 1", 1, testSocketSSH, &sshData1) < 0)
ret = -1;
@@ -509,7 +509,7 @@ mymain(void)
.noTTY = true,
.noVerify = false,
.path = "/tmp/socket",
- .expectOut = "-p 9000 -l fred -T -o BatchMode=yes -e none somehost netcat -U /tmp/socket\n",
+ .expectOut = "-p 9000 -l fred -T -o BatchMode=yes -e none somehost sh -c 'if netcat -q 2>&1 | grep \"requires an argument\" >/dev/null 2>&1; then ARG=-q0;fi;netcat $ARG -U /tmp/socket'\n",
};
if (virtTestRun("SSH test 2", 1, testSocketSSH, &sshData2) < 0)
ret = -1;
@@ -522,7 +522,7 @@ mymain(void)
.noTTY = false,
.noVerify = true,
.path = "/tmp/socket",
- .expectOut = "-p 9000 -l fred -o StrictHostKeyChecking=no somehost netcat -U /tmp/socket\n",
+ .expectOut = "-p 9000 -l fred -o StrictHostKeyChecking=no somehost sh -c 'if netcat -q 2>&1 | grep \"requires an argument\" >/dev/null 2>&1; then ARG=-q0;fi;netcat $ARG -U /tmp/socket'\n",
};
if (virtTestRun("SSH test 3", 1, testSocketSSH, &sshData3) < 0)
ret = -1;
@@ -538,7 +538,8 @@ mymain(void)
struct testSSHData sshData5 = {
.nodename = "crashyhost",
.path = "/tmp/socket",
- .expectOut = "crashyhost nc -U /tmp/socket\n",
+ .expectOut = "crashyhost sh -c 'if nc -q 2>&1 | grep \"requires an argument\" >/dev/null 2>&1; then ARG=-q0;fi;nc $ARG -U /tmp/socket'\n",
+
.dieEarly = true,
};
if (virtTestRun("SSH test 5", 1, testSocketSSH, &sshData5) < 0)
@@ -549,7 +550,7 @@ mymain(void)
.path = "/tmp/socket",
.keyfile = "/root/.ssh/example_key",
.noVerify = true,
- .expectOut = "-i /root/.ssh/example_key -o StrictHostKeyChecking=no example.com nc -U /tmp/socket\n",
+ .expectOut = "-i /root/.ssh/example_key -o StrictHostKeyChecking=no example.com sh -c 'if nc -q 2>&1 | grep \"requires an argument\" >/dev/null 2>&1; then ARG=-q0;fi;nc $ARG -U /tmp/socket'\n",
};
if (virtTestRun("SSH test 6", 1, testSocketSSH, &sshData6) < 0)
ret = -1;
--
1.7.6.3
13 years, 6 months
[libvirt] [PATCH] storage: plug memory leak on error
by Eric Blake
Detected by Coverity. Present since commit 82c1740.
* src/storage/storage_backend_logical.c
(virStorageBackendLogicalMakeVol): Fix leak.
---
Pushing under the trivial rule.
src/storage/storage_backend_logical.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/src/storage/storage_backend_logical.c b/src/storage/storage_backend_logical.c
index 51624a7..50d0407 100644
--- a/src/storage/storage_backend_logical.c
+++ b/src/storage/storage_backend_logical.c
@@ -231,16 +231,17 @@ virStorageBackendLogicalMakeVol(virStoragePoolObjPtr pool,
if (!(offset_str = strndup(p + vars[j + 1].rm_so, len))) {
virReportOOMError();
goto cleanup;
}
if (virStrToLong_ull(offset_str, NULL, 10, &offset) < 0) {
virStorageReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("malformed volume extent offset value"));
+ VIR_FREE(offset_str);
goto cleanup;
}
VIR_FREE(offset_str);
vol->source.extents[vol->source.nextent].start = offset * size;
vol->source.extents[vol->source.nextent].end = (offset * size) + length;
vol->source.nextent++;
--
1.7.4.4
13 years, 6 months
[libvirt] How to identify a VirtFS using libvirt
by Richard Maciel
Hi,
Is there any way to fetch info on a VirtFS share, aside from reading the
guest's XML file?
For instance, I'd like to read the source and target dir of the VirtFS
mount created on guest by using the following XML code:
<filesystem type='mount' accessmode='passthrough'>
<source dir='/mnt/9p_setup'/>
<target dir='9p_test'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x07'
function='0x0'/>
</filesystem>
I tried to use the pool and volume-related functions on the API, but
that didn't work.
Richard Maciel
13 years, 6 months
[libvirt] [PATCH] qemu: fix text block info parsing
by Eric Blake
Detected by Coverity. p (the pointer to the string) is always true;
when in reality, we wanted to know whether the integer value of the
just-parsed string is '0' or '1'. Logic bug since commit b1b5b51.
* src/qemu/qemu_monitor_text.c (qemuMonitorTextGetBlockInfo): Set
results to proper value.
---
Second bug introduced by the same commit. And I think I reviewed
it originally. Sorry for not catching it earlier.
src/qemu/qemu_monitor_text.c | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/qemu/qemu_monitor_text.c b/src/qemu/qemu_monitor_text.c
index 1eb9846..49c469b 100644
--- a/src/qemu/qemu_monitor_text.c
+++ b/src/qemu/qemu_monitor_text.c
@@ -817,19 +817,19 @@ int qemuMonitorTextGetBlockInfo(qemuMonitorPtr mon,
if (virStrToLong_i(p, &dummy, 10, &tmp) == -1)
VIR_DEBUG("error reading removable: %s", p);
else
- info->removable = p != NULL;
+ info->removable = tmp != 0;
} else if (STRPREFIX(p, "locked=")) {
p += strlen("locked=");
if (virStrToLong_i(p, &dummy, 10, &tmp) == -1)
VIR_DEBUG("error reading locked: %s", p);
else
- info->locked = p ? true : false;
+ info->locked = tmp != 0;
} else if (STRPREFIX(p, "tray_open=")) {
p += strlen("tray_open=");
if (virStrToLong_i(p, &dummy, 10, &tmp) == -1)
VIR_DEBUG("error reading tray_open: %s", p);
else
- info->tray_open = p ? true : false;
+ info->tray_open = tmp != 0;
} else {
/* ignore because we don't parse all options */
}
--
1.7.4.4
13 years, 6 months