[libvirt] [PATCH] ESX: Add AnyType_Serialize routine to esx_vi_types.c
by Ata E Husain Bohra
Add esxVI_AnyType_Serialize routine to allow serialization
of objects containing variables of type "AnyType". The routine
attempts to determine the type of the object that covers:
boolean, long, int, string, short, byte.
If variables does not fall under any above mentioned types
then it is added as "anyType".
---
src/esx/esx_vi_types.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
src/esx/esx_vi_types.h | 3 ++-
2 files changed, 50 insertions(+), 1 deletion(-)
diff --git a/src/esx/esx_vi_types.c b/src/esx/esx_vi_types.c
index d1f91ff..2076ce4 100644
--- a/src/esx/esx_vi_types.c
+++ b/src/esx/esx_vi_types.c
@@ -1130,6 +1130,54 @@ esxVI_AnyType_Deserialize(xmlNodePtr node, esxVI_AnyType **anyType)
+int
+esxVI_AnyType_Serialize(esxVI_AnyType *anyType, const char *element,
+ virBufferPtr output)
+{
+ if (element == NULL || output == NULL) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Invalid argument"));
+ return -1;
+ }
+
+ if (anyType == NULL || anyType->value == NULL) {
+ return 0;
+ }
+
+ switch (anyType->type) {
+ case esxVI_Type_Boolean:
+ ESV_VI__XML_TAG__OPEN(output, element, "xsd:boolean");
+ break;
+ case esxVI_Type_String:
+ ESV_VI__XML_TAG__OPEN(output, element, "xsd:string");
+ break;
+ case esxVI_Type_Short:
+ ESV_VI__XML_TAG__OPEN(output, element, "xsd:short");
+ break;
+ case esxVI_Type_Byte:
+ ESV_VI__XML_TAG__OPEN(output, element, "xsd:byte");
+ break;
+ case esxVI_Type_Int:
+ ESV_VI__XML_TAG__OPEN(output, element, "xsd:int");
+ break;
+ case esxVI_Type_Long:
+ ESV_VI__XML_TAG__OPEN(output, element, "xsd:long");
+ break;
+ case esxVI_Type_Undefined:
+ case esxVI_Type_Other:
+ default:
+ ESV_VI__XML_TAG__OPEN(output, element, "xsd:anyType");
+ break;
+ }
+
+ virBufferAdd(output, anyType->value, -1);
+
+ ESV_VI__XML_TAG__CLOSE(output, element);
+
+ return 0;
+}
+
+
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* XSD: String
*/
diff --git a/src/esx/esx_vi_types.h b/src/esx/esx_vi_types.h
index 92dc16f..5150377 100644
--- a/src/esx/esx_vi_types.h
+++ b/src/esx/esx_vi_types.h
@@ -161,7 +161,8 @@ const char *esxVI_AnyType_TypeToString(esxVI_AnyType *anyType);
int esxVI_AnyType_ExpectType(esxVI_AnyType *anyType, esxVI_Type type);
int esxVI_AnyType_DeepCopy(esxVI_AnyType **dest, esxVI_AnyType *src);
int esxVI_AnyType_Deserialize(xmlNodePtr node, esxVI_AnyType **anyType);
-
+int esxVI_AnyType_Serialize(esxVI_AnyType *anyType, const char *element,
+ virBufferPtr output);
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
--
1.7.9.5
11 years, 9 months
[libvirt] [PATCHv2 0/5] Add API to allow TCP connection tunelling
by Peter Krempa
This series adds ability for the qemu driver to tunnel connections to TCP
ports from the host. This is useful for enabling remote VNC/SPICE sessions
without the need to configure SSH tunnels or portforwards and without the
need to open the ports for public.
There's also an advantage for tools such as virt-viewer that have to guess the remote
connection parameters and you have to hope that nothing is in your way. With
spice/VNC clients that have support for read/write callbacks, this would allow also
direct connection without an intermediate socket.
The API and tunelling works but there's no (stable and good working) client for
this API. I hacked up a dirty netcat-like terminal into virsh for testing
purposes (see patch 5/5) but that isn't what I'd like to see.
The client should be able to open a listening socket and when a client connects
to it, it opens a stream and connects it to the remote host.
For the client there are two options:
1) do all the stuff in virsh: + one tool to rule them all
- i'd like to daemonize it and I don't know if that's okay in virsh
2) add a new tool "virtunnel": + less virsh pollution
- separate tool ...
As nobody responded, I'd like to re-ask for someones opinion on this.
(note: this is my personal effort, I'm annoyed of opening ssh tunnels to remote displays on my server
and I don't want to open the ports to public. )
After this it would be great to add support for this to virt-viewer. I will have a look at that later.
----
Diff to v1:
- fixed error reporting in 2/5
- documented limitation to "localhost" in 3/5
- fixed possible segfault in 4/5
---
Peter Krempa (5):
api: Add API to allow TCP tunneling through streams to the host
fdstream: Add support for TCP connections of streams
qemu: Add configuration options to enable TCP tunelling
qemu: Implement virNodeTunnelTcp for the qemu driver
NOT_TO_BE_APPLIED_UPSTREAM: quick and dirty virsh client to test the
stuff
include/libvirt/libvirt.h.in | 11 +++++++
src/driver.h | 8 +++++
src/fdstream.c | 73 ++++++++++++++++++++++++++++++++++++++++++++
src/fdstream.h | 5 +++
src/libvirt.c | 67 ++++++++++++++++++++++++++++++++++++++++
src/libvirt_private.syms | 1 +
src/libvirt_public.syms | 1 +
src/qemu/qemu.conf | 16 ++++++++++
src/qemu/qemu_conf.c | 26 ++++++++++++++++
src/qemu/qemu_conf.h | 13 ++++++++
src/qemu/qemu_driver.c | 48 +++++++++++++++++++++++++++++
src/remote/remote_driver.c | 1 +
src/remote/remote_protocol.x | 9 +++++-
src/remote_protocol-structs | 6 ++++
src/rpc/gendispatch.pl | 1 +
tools/console.c | 66 +++++++++++++++++++++------------------
tools/console.h | 9 ++----
tools/virsh-domain.c | 17 +++++++++--
tools/virsh-host.c | 60 ++++++++++++++++++++++++++++++++++++
19 files changed, 397 insertions(+), 41 deletions(-)
--
1.8.0
11 years, 9 months
[libvirt] [libvirt-glib 1/2] Use g_strlcpy instead of strncpy
by Christophe Fergeau
This guarantees that the string will be nul-terminated. Coverity
warned about this issue.
---
libvirt-gobject/libvirt-gobject-connection.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libvirt-gobject/libvirt-gobject-connection.c b/libvirt-gobject/libvirt-gobject-connection.c
index 91cc535..0525323 100644
--- a/libvirt-gobject/libvirt-gobject-connection.c
+++ b/libvirt-gobject/libvirt-gobject-connection.c
@@ -1583,7 +1583,7 @@ GVirNodeInfo *gvir_connection_get_node_info(GVirConnection *conn,
}
ret = g_slice_new(GVirNodeInfo);
- strncpy (ret->model, info.model, sizeof (ret->model));
+ g_strlcpy (ret->model, info.model, sizeof (ret->model));
ret->memory = info.memory;
ret->cpus = info.cpus;
ret->mhz = info.mhz;
--
1.8.0.2
11 years, 10 months
[libvirt] [PATCH 1/1] ppc64 cpu features
by Li Zhang
From: Li Zhang <zhlcindy(a)linux.vnet.ibm.com>
This patch adds a CPU feature "powernv" identifying IBM Power
processor that supports native hypervisor e.g. KVM. This can
be used by virtualization management software to determine
the CPU capabilities. PVR doesn't indicate whether it a
host or a guest CPU. So, we use /proc/cpuinfo to get the
platform information (PowerNV) and use that to set the
"powernv" flag.
Signed-off-by: Dipankar Sarma <dipankar(a)in.ibm.com>
Signed-off-by: Li Zhang <zhlcindy(a)linux.vnet.ibm.com>
---
src/cpu/cpu_map.xml | 9 ++
src/cpu/cpu_powerpc.c | 349 ++++++++++++++++++++++++++++++++++++++----------
src/cpu/cpu_ppc_data.h | 4 +
src/util/sysinfo.c | 2 +-
4 files changed, 294 insertions(+), 70 deletions(-)
diff --git a/src/cpu/cpu_map.xml b/src/cpu/cpu_map.xml
index eb69a34..6b1f9b9 100644
--- a/src/cpu/cpu_map.xml
+++ b/src/cpu/cpu_map.xml
@@ -587,14 +587,23 @@
<arch name='ppc64'>
<!-- vendor definitions -->
<vendor name='IBM' string='PowerPC'/>
+ <feature name='powernv'> <!-- SYSTEMID_POWERNV -->
+ <systemid platform='0x00000001'/>
+ </feature>
<!-- IBM-based CPU models -->
<model name='POWER7'>
+ <feature name='powernv'/>
+ <systemid pvr='0x003f0200'/>
<vendor name='IBM'/>
</model>
<model name='POWER7_v2.1'>
+ <feature name='powernv'/>
+ <systemid pvr='0x003f0201'/>
<vendor name='IBM'/>
</model>
<model name='POWER7_v2.3'>
+ <feature name='powernv'/>
+ <systemid pvr='0x003f0203'/>
<vendor name='IBM'/>
</model>
</arch>
diff --git a/src/cpu/cpu_powerpc.c b/src/cpu/cpu_powerpc.c
index ac10789..2135944 100644
--- a/src/cpu/cpu_powerpc.c
+++ b/src/cpu/cpu_powerpc.c
@@ -33,6 +33,7 @@
#include "cpu_map.h"
#include "buf.h"
+#include "sysinfo.h"
#define VIR_FROM_THIS VIR_FROM_CPU
@@ -44,16 +45,9 @@ struct cpuPowerPC {
uint32_t pvr;
};
-static const struct cpuPowerPC cpu_defs[] = {
- {"POWER7", "IBM", 0x003f0200},
- {"POWER7_v2.1", "IBM", 0x003f0201},
- {"POWER7_v2.3", "IBM", 0x003f0203},
- {NULL, NULL, 0xffffffff}
-};
-
-
struct ppc_vendor {
char *name;
+ uint32_t pvr;
struct ppc_vendor *next;
};
@@ -64,64 +58,191 @@ struct ppc_model {
struct ppc_model *next;
};
+struct ppc_feature {
+ char *name;
+ union cpuData *data;
+ struct ppc_feature *next;
+};
+
struct ppc_map {
struct ppc_vendor *vendors;
+ struct ppc_feature *features;
struct ppc_model *models;
};
+static void
+ppcDataSubtract(union cpuData *data1,
+ const union cpuData *data2)
+{
+ data1->ppc.platform &= ~data2->ppc.platform;
+}
+
+static bool
+ppcDataIsSubset(const union cpuData *data,
+ const union cpuData *subset)
+{
+ if (subset->ppc.platform &&
+ (data->ppc.platform & subset->ppc.platform) == subset->ppc.platform)
+ return true;
+
+ return false;
+}
+
+static void
+PowerPCDataFree(union cpuData *data)
+{
+ if (data == NULL)
+ return;
+ VIR_FREE(data);
+}
+
+
+static union cpuData *
+ppcDataCopy(const union cpuData *data)
+{
+ union cpuData *copy = NULL;
+
+ if (VIR_ALLOC(copy) < 0) {
+ PowerPCDataFree(copy);
+ return NULL;
+ }
+ copy->ppc = data->ppc;
+ return copy;
+}
+
+
+/* also removes all detected features from data */
static int
-ConvertModelVendorFromPVR(char ***model,
- char ***vendor,
- uint32_t pvr)
+ppcDataToCPUFeatures(virCPUDefPtr cpu,
+ int policy,
+ union cpuData *data,
+ const struct ppc_map *map)
{
- int i;
+ const struct ppc_feature *feature = map->features;
- for (i = 0; cpu_defs[i].name; i++) {
- if (cpu_defs[i].pvr == pvr) {
- **model = strdup(cpu_defs[i].name);
- **vendor = strdup(cpu_defs[i].vendor);
- return 0;
+ while (feature != NULL) {
+ if (ppcDataIsSubset(data, feature->data)) {
+ ppcDataSubtract(data, feature->data);
+ if (virCPUDefAddFeature(cpu, feature->name, policy) < 0)
+ return -1;
}
+ feature = feature->next;
}
- virReportError(VIR_ERR_INTERNAL_ERROR,
- "%s", _("Missing the definition of this model"));
- return -1;
+ return 0;
}
-static int
-ConvertPVRFromModel(const char *model,
- uint32_t *pvr)
+static struct ppc_feature *
+ppcFeatureNew(void)
{
- int i;
+ struct ppc_feature *feature;
- for (i = 0; cpu_defs[i].name; i++) {
- if (STREQ(cpu_defs[i].name, model)) {
- *pvr = cpu_defs[i].pvr;
- return 0;
- }
+ if (VIR_ALLOC(feature) < 0)
+ return NULL;
+
+ if (VIR_ALLOC(feature->data) < 0) {
+ VIR_FREE(feature);
+ return NULL;
+ }
+
+ return feature;
+}
+
+
+static void
+ppcFeatureFree(struct ppc_feature *feature)
+{
+ if (feature == NULL)
+ return;
+
+ VIR_FREE(feature->name);
+ PowerPCDataFree(feature->data);
+ VIR_FREE(feature);
+}
+
+
+static struct ppc_feature *
+ppcFeatureFind(const struct ppc_map *map,
+ const char *name)
+{
+ struct ppc_feature *feature;
+
+ feature = map->features;
+ while (feature != NULL) {
+ if (STREQ(feature->name, name))
+ return feature;
+
+ feature = feature->next;
}
- virReportError(VIR_ERR_INTERNAL_ERROR,
- "%s", _("Missing the definition of this model"));
- return -1;
+ return NULL;
}
static int
-cpuMatch(const union cpuData *data,
- char **cpu_model,
- char **cpu_vendor,
- const struct ppc_model *model)
+ppcFeatureLoad(xmlXPathContextPtr ctxt,
+ struct ppc_map *map)
{
+ xmlNodePtr *nodes = NULL;
+ xmlNodePtr ctxt_node = ctxt->node;
+ struct ppc_feature *feature;
int ret = 0;
+ unsigned long platform = 0;
+ unsigned long pvr = 0;
+ int ret_platform;
+ int ret_pvr;
+ int n;
+
+ if (!(feature = ppcFeatureNew()))
+ goto no_memory;
+
+ feature->name = virXPathString("string(@name)", ctxt);
+ if (feature->name == NULL) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ "%s", _("Missing CPU feature name"));
+ goto ignore;
+ }
+
+ if (ppcFeatureFind(map, feature->name)) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("CPU feature %s already defined"), feature->name);
+ goto ignore;
+ }
+
+ n = virXPathNodeSet("./systemid", ctxt, &nodes);
+ if (n < 0)
+ goto ignore;
+
+ ctxt->node = nodes[0];
+ ret_platform = virXPathULongHex("string(@platform)", ctxt, &platform);
+ ret_pvr = virXPathULongHex("string(@pvr)", ctxt, &pvr);
+ if (ret_platform < 0 && ret_pvr < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Invalid systemid in %s feature"), feature->name);
+ goto ignore;
+ }
+ feature->data->ppc.platform = platform;
+ feature->data->ppc.pvr = pvr;
- ret = ConvertModelVendorFromPVR(&cpu_model, &cpu_vendor, data->ppc.pvr);
+ if (map->features == NULL)
+ map->features = feature;
+ else {
+ feature->next = map->features;
+ map->features = feature;
+ }
- if (STREQ(model->name, *cpu_model) &&
- STREQ(model->vendor->name, *cpu_vendor))
- ret = 1;
+out:
+ ctxt->node = ctxt_node;
+ VIR_FREE(nodes);
return ret;
+
+no_memory:
+ virReportOOMError();
+ ret = -1;
+
+ignore:
+ ppcFeatureFree(feature);
+ goto out;
}
@@ -171,6 +292,66 @@ ppcModelFind(const struct ppc_map *map,
return NULL;
}
+/* also removes bits corresponding to vendor string from data */
+static const struct ppc_vendor *
+ppcDataToVendor(union cpuData *data,
+ const struct ppc_map *map)
+{
+ const struct ppc_vendor *vendor = map->vendors;
+
+ while (vendor) {
+ if (data->ppc.pvr == vendor->pvr)
+ return vendor;
+ vendor = vendor->next;
+ }
+
+ return NULL;
+}
+
+
+static virCPUDefPtr
+ppcDataToCPU(const union cpuData *data,
+ const struct ppc_model *model,
+ const struct ppc_map *map)
+{
+ virCPUDefPtr cpu;
+ union cpuData *copy = NULL;
+ union cpuData *modelData = NULL;
+ const struct ppc_vendor *vendor;
+
+ if (VIR_ALLOC(cpu) < 0 ||
+ !(cpu->model = strdup(model->name)) ||
+ !(copy = ppcDataCopy(data)) ||
+ !(modelData = ppcDataCopy(model->data)))
+ goto no_memory;
+
+ if ((vendor = ppcDataToVendor(copy, map)) &&
+ !(cpu->vendor = strdup(vendor->name)))
+ goto no_memory;
+
+ ppcDataSubtract(copy, modelData);
+ ppcDataSubtract(modelData, data);
+
+ /* because feature policy is ignored for host CPU */
+ cpu->type = VIR_CPU_TYPE_GUEST;
+
+ if (ppcDataToCPUFeatures(cpu, VIR_CPU_FEATURE_REQUIRE, copy, map) ||
+ ppcDataToCPUFeatures(cpu, VIR_CPU_FEATURE_DISABLE, modelData, map))
+ goto error;
+
+cleanup:
+ PowerPCDataFree(modelData);
+ PowerPCDataFree(copy);
+ return cpu;
+
+no_memory:
+ virReportOOMError();
+error:
+ virCPUDefFree(cpu);
+ cpu = NULL;
+ goto cleanup;
+}
+
static struct ppc_vendor *
ppcVendorFind(const struct ppc_map *map,
const char *name)
@@ -256,6 +437,9 @@ ppcModelLoad(xmlXPathContextPtr ctxt,
xmlNodePtr *nodes = NULL;
struct ppc_model *model;
char *vendor = NULL;
+ unsigned long pvr = 0, platform = 0;
+ int ret_platform, ret_pvr;
+ int n;
int ret = -1;
if (!(model = ppcModelNew()))
@@ -268,10 +452,20 @@ ppcModelLoad(xmlXPathContextPtr ctxt,
goto ignore;
}
- ret = ConvertPVRFromModel(model->name, &model->data->ppc.pvr);
- if (ret < 0)
- goto ignore;
+ n = virXPathNodeSet("./systemid", ctxt, &nodes);
+ if (n < 0)
+ goto ignore;
+ ctxt->node = nodes[0];
+ ret_platform = virXPathULongHex("string(@platform)", ctxt, &platform);
+ ret_pvr = virXPathULongHex("string(@pvr)", ctxt, &pvr);
+ if (ret_platform < 0 && ret_pvr < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Invalid systemid in %s model"), model->name);
+ goto ignore;
+ }
+ model->data->ppc.platform = platform;
+ model->data->ppc.pvr = pvr;
if (virXPathBoolean("boolean(./vendor)", ctxt)) {
vendor = virXPathString("string(./vendor/@name)", ctxt);
@@ -324,6 +518,8 @@ ppcMapLoadCallback(enum cpuMapElement element,
return ppcVendorLoad(ctxt, map);
case CPU_MAP_ELEMENT_MODEL:
return ppcModelLoad(ctxt, map);
+ case CPU_MAP_ELEMENT_FEATURE:
+ return ppcFeatureLoad(ctxt, map);
default:
break;
}
@@ -385,6 +581,7 @@ ppcModelCopy(const struct ppc_model *model)
}
copy->data->ppc.pvr = model->data->ppc.pvr;
+ copy->data->ppc.platform = model->data->ppc.platform;
copy->vendor = model->vendor;
return copy;
@@ -437,8 +634,6 @@ PowerPCDecode(virCPUDefPtr cpu,
const struct ppc_model *candidate;
virCPUDefPtr cpuCandidate;
virCPUDefPtr cpuModel = NULL;
- char *cpu_vendor = NULL;
- char *cpu_model = NULL;
unsigned int i;
if (data == NULL || (map = ppcLoadMap()) == NULL)
@@ -475,13 +670,30 @@ PowerPCDecode(virCPUDefPtr cpu,
goto next;
}
- if (VIR_ALLOC(cpuCandidate) < 0) {
- virReportOOMError();
+ if (!(cpuCandidate = ppcDataToCPU(data, candidate, map)))
goto out;
+
+ if (candidate->vendor && cpuCandidate->vendor &&
+ STRNEQ(candidate->vendor->name, cpuCandidate->vendor)) {
+ VIR_DEBUG("CPU vendor %s of model %s differs from %s; ignoring",
+ candidate->vendor->name, candidate->name,
+ cpuCandidate->vendor);
+ virCPUDefFree(cpuCandidate);
+ goto next;
}
- cpuCandidate->model = strdup(candidate->name);
- cpuCandidate->vendor = strdup(candidate->vendor->name);
+ if (cpu->type == VIR_CPU_TYPE_HOST) {
+ cpuCandidate->type = VIR_CPU_TYPE_HOST;
+ for (i = 0; i < cpuCandidate->nfeatures; i++) {
+ switch (cpuCandidate->features[i].policy) {
+ case VIR_CPU_FEATURE_DISABLE:
+ virCPUDefFree(cpuCandidate);
+ goto next;
+ default:
+ cpuCandidate->features[i].policy = -1;
+ }
+ }
+ }
if (preferred && STREQ(cpuCandidate->model, preferred)) {
virCPUDefFree(cpuModel);
@@ -489,19 +701,12 @@ PowerPCDecode(virCPUDefPtr cpu,
break;
}
- ret = cpuMatch(data, &cpu_model, &cpu_vendor, candidate);
- if (ret < 0) {
- VIR_FREE(cpuCandidate);
- goto out;
- } else if (ret == 1) {
- cpuCandidate->model = cpu_model;
- cpuCandidate->vendor = cpu_vendor;
+ if (cpuModel == NULL
+ || cpuModel->nfeatures > cpuCandidate->nfeatures) {
virCPUDefFree(cpuModel);
cpuModel = cpuCandidate;
- break;
- }
-
- virCPUDefFree(cpuCandidate);
+ }else
+ virCPUDefFree(cpuCandidate);
next:
candidate = candidate->next;
@@ -515,6 +720,8 @@ PowerPCDecode(virCPUDefPtr cpu,
cpu->model = cpuModel->model;
cpu->vendor = cpuModel->vendor;
+ cpu->nfeatures = cpuModel->nfeatures;
+ cpu->features = cpuModel->features;
VIR_FREE(cpuModel);
ret = 0;
@@ -537,19 +744,11 @@ static uint32_t ppc_mfpvr(void)
}
#endif
-static void
-PowerPCDataFree(union cpuData *data)
-{
- if (data == NULL)
- return;
-
- VIR_FREE(data);
-}
-
static union cpuData *
PowerPCNodeData(void)
{
union cpuData *data;
+ virSysinfoDefPtr hostinfo;
if (VIR_ALLOC(data) < 0) {
virReportOOMError();
@@ -561,6 +760,18 @@ PowerPCNodeData(void)
data->ppc.pvr = ppc_mfpvr();
#endif
+ hostinfo = virSysinfoRead();
+ if (hostinfo == NULL) {
+ VIR_FREE(data);
+ return NULL;
+ }
+
+ data->ppc.platform &= ~VIR_CPU_PPC64_POWERNV;
+
+ if (STREQ(hostinfo->system_family, "PowerNV"))
+ data->ppc.platform |= VIR_CPU_PPC64_POWERNV;
+ virSysinfoDefFree(hostinfo);
+
return data;
}
diff --git a/src/cpu/cpu_ppc_data.h b/src/cpu/cpu_ppc_data.h
index 685332a..0e691ce 100644
--- a/src/cpu/cpu_ppc_data.h
+++ b/src/cpu/cpu_ppc_data.h
@@ -28,6 +28,10 @@
struct cpuPPCData {
uint32_t pvr;
+ uint32_t platform; /* Bitflag indicating platform features */
};
+#define VIR_CPU_PPC64_NONE 0x0
+#define VIR_CPU_PPC64_POWERNV 0x1
+
#endif /* __VIR_CPU_PPC_DATA_H__ */
diff --git a/src/util/sysinfo.c b/src/util/sysinfo.c
index 6a5db80..5f98986 100644
--- a/src/util/sysinfo.c
+++ b/src/util/sysinfo.c
@@ -234,7 +234,7 @@ virSysinfoRead(void) {
if (VIR_ALLOC(ret) < 0)
goto no_memory;
- if (virFileReadAll(CPUINFO, 2048, &outbuf) < 0) {
+ if (virFileReadAll(CPUINFO, 8192, &outbuf) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Failed to open %s"), CPUINFO);
return NULL;
--
1.7.10.1
11 years, 10 months
[libvirt] [PATCH] qemu: fix QEMU_CAPS_NO_ACPI detection
by Ján Tomko
In commit c4bbaaf8, caps->arch was checked uninitialized, rendering the
whole check useless.
This patch moves the conditional setting of QEMU_CAPS_NO_ACPI to
qemuCapsInitQMP, and removes the no longer needed exception for S390.
It also clears the flag for all non-x86 archs instead of just S390 in
qemuCapsInitHelp.
---
src/qemu/qemu_capabilities.c | 29 ++++++++---------------------
1 files changed, 8 insertions(+), 21 deletions(-)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 167cdb2..e0d0c2a 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -2175,13 +2175,11 @@ qemuCapsInitHelp(qemuCapsPtr caps, uid_t runUid, gid_t runGid)
if (caps->arch == VIR_ARCH_X86_64 ||
caps->arch == VIR_ARCH_I686) {
qemuCapsSet(caps, QEMU_CAPS_PCI_MULTIBUS);
- }
-
- /* S390 and probably other archs do not support no-acpi -
- maybe the qemu option parsing should be re-thought. */
- if (caps->arch == VIR_ARCH_S390 ||
- caps->arch == VIR_ARCH_S390X)
+ } else {
+ /* -no-acpi is not supported on other archs
+ * even if qemu reports it in -help */
qemuCapsClear(caps, QEMU_CAPS_NO_ACPI);
+ }
/* qemuCapsExtractDeviceStr will only set additional caps if qemu
* understands the 0.13.0+ notion of "-device driver,". */
@@ -2260,13 +2258,6 @@ qemuCapsInitQMPBasic(qemuCapsPtr caps)
qemuCapsSet(caps, QEMU_CAPS_DRIVE_CACHE_DIRECTSYNC);
qemuCapsSet(caps, QEMU_CAPS_NO_SHUTDOWN);
qemuCapsSet(caps, QEMU_CAPS_DRIVE_CACHE_UNSAFE);
-
- /* ACPI is only supported on x86, PPC or
- * other platforms don't support it*/
- if (caps->arch == VIR_ARCH_I686 ||
- caps->arch == VIR_ARCH_X86_64)
- qemuCapsSet(caps, QEMU_CAPS_NO_ACPI);
-
qemuCapsSet(caps, QEMU_CAPS_FSDEV_READONLY);
qemuCapsSet(caps, QEMU_CAPS_VIRTIO_BLK_SG_IO);
qemuCapsSet(caps, QEMU_CAPS_DRIVE_COPY_ON_READ);
@@ -2402,16 +2393,12 @@ qemuCapsInitQMP(qemuCapsPtr caps,
}
VIR_FREE(archstr);
- /* Currently only x86_64 and i686 support PCI-multibus. */
+ /* Currently only x86_64 and i686 support PCI-multibus and -no-acpi. */
if (caps->arch == VIR_ARCH_X86_64 ||
- caps->arch == VIR_ARCH_I686)
+ caps->arch == VIR_ARCH_I686) {
qemuCapsSet(caps, QEMU_CAPS_PCI_MULTIBUS);
-
- /* S390 and probably other archs do not support no-acpi -
- maybe the qemu option parsing should be re-thought. */
- if (caps->arch == VIR_ARCH_S390 ||
- caps->arch == VIR_ARCH_S390X)
- qemuCapsClear(caps, QEMU_CAPS_NO_ACPI);
+ qemuCapsSet(caps, QEMU_CAPS_NO_ACPI);
+ }
if (qemuCapsProbeQMPCommands(caps, mon) < 0)
goto cleanup;
--
1.7.8.6
11 years, 10 months
[libvirt] [PATCH 0/9] Add ability to connect to LXC namespaces
by Daniel P. Berrange
This series introduces an LXC specific library libvirt-lxc.so
which adds ability for a process to connect to the namespaces
used by an LXC container from outside. It uses FD passing
magic to allow the caller to connect, even if it is not root.
11 years, 10 months
[libvirt] Connection release is not correct in libvirt and libvrt java
by Benjamin Wang (gendwang)
Hi,
The following is the current code to release connection in libvirt.
int
virConnectClose(virConnectPtr conn)
{
...
if (!VIR_IS_CONNECT(conn)) {
virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
goto error;
}
...
error:
virDispatchError(NULL);
return ret;
}
Now if the cable is unplugged and the application call virConnectClose to release connection, the code will enter into the error procedure, the connection
Can't be released. I have changed the following two parts to fix this issue. Please give your comments:
Changed Code1:
int
virConnectClose(virConnectPtr conn)
{
...
+ if(NULL == conn) {
+ return 0;
+ }
...
- if (!VIR_IS_CONNECT(conn)) {
- virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
- goto error;
- }
...
error:
virDispatchError(NULL);
return ret;
}
Changed Code2:
int
virUnrefConnect(virConnectPtr conn) {
...
+ if(NULL == conn) {
+ return 0;
+ }
- if ((!VIR_IS_CONNECT(conn))) {
- virLibConnError(VIR_ERR_INVALID_ARG, _("no connection"));
- return -1;
- }
...
}
For libvirt java, there are similar issue. I have changed code as following in Collect.java. Please also give your comments.
public int close() throws LibvirtException {
int success = 0;
if (VCP != null) {
+ try {
success = libvirt.virConnectClose(VCP);
processError();
+ }
+ finally {
// If leave an invalid pointer dangling around JVM crashes and burns
// if someone tries to call a method on us
// We rely on the underlying libvirt error handling to detect that
// it's called with a null virConnectPointer
VCP = null;
+ }
}
return success;
}
B.R.
Benjamin Wang
11 years, 11 months
[libvirt] [PATCH v2 00/11] Rework storage migration
by Michal Privoznik
This patch set re-implements migration with storage for enough new qemu.
Currently, you can migrate a domain to a host without need for shared storage.
This is done by setting 'blk' or 'inc' attribute (representing
VIR_MIGRATE_NON_SHARED_DISK and VIR_MIGRATE_NON_SHARED_INC flags respectively)
of 'migrate' monitor command. However, the qemu implementation is
buggy and applications are advised to switch to new impementation
which, moreover, offers some nice features, like migrating only explicitly
specified disks.
The new functionality is controlled via 'nbd-server-*' and 'drive-mirror'
commands. The flow is meant to look like this:
1) User invokes libvirt's migrate functionality.
2) libvirt checks that no block jobs are active on the source.
3) libvirt starts the destination QEMU and sets up the NBD server using the
nbd-server-start and nbd-server-add commands.
4) libvirt starts drive-mirror with a destination pointing to the remote NBD
server, for example nbd:host:port:exportname=diskname (where diskname is the
-drive id specified on the destination).
5) once all mirroring jobs reach steady state, libvirt invokes the migrate
command.
6) once migration completed, libvirt invokes the nbd-server-stop command on the
destination QEMU.
If we just skip the 2nd step and there is an active block-job, qemu will fail in
step 4. No big deal.
Since we try to NOT break migration and keep things compatible, this feature is
enabled iff both sides support it. Since there's obvious need for some data
transfer between src and dst, I've put it into qemuCookieMigration:
1) src -> dest: (QEMU_MIGRATION_PHASE_BEGIN3 -> QEMU_MIGRATION_PHASE_PREPARE)
<nbd>
<disk size='17179869184'/>
</nbd>
Hey destination, I know how to use this cool new feature. Moreover,
these are the disks I'll send you. Each one of them is X bytes big.
It's one of the prerequisite - the file (disk->src) on dst exists and has
at least the same size as on dst.
2) dst -> src: (QEMU_MIGRATION_PHASE_PREPARE -> QEMU_MIGRATION_PHASE_PERFORM3)
<nbd port='X'/>
Okay, I (destination) support this feature as well. I've created all
files as you (src) told me to and you can start rolling data. I am listening
on port X.
3) src -> dst: (QEMU_MIGRATION_PHASE_PERFORM3 -> QEMU_MIGRATION_PHASE_FINISH3)
<nbd port='-1'/>
Migration completed, destination, you may shut the NBD server down.
If either src or dst doesn't support NBD, it is not used and whole process fall
backs to old implementation.
diff to v1:
-Eric's and Daniel's suggestions worked in. To point out the bigger ones:
don't do NBD style when TUNNELLED requested, added 'b:writable' to
'nbd-server-add'
-drop '/qemu-migration/nbd/disk/@src' attribute from migration cookie.
As pointed out by Jirka, disk->src can be changed during migration (e.g. by
migration hook or by passed xml). So I've tried (as suggested on the list)
passing disk alias. However, since qemu hasn't been started on destination yet,
the aliases hasn't been generated yet. So we have to rely on ordering
completely.
The patches 1,3 and 5 has been ACKed already.
Michal Privoznik (11):
qemu: Introduce NBD_SERVER capability
Introduce NBD migration cookie
qemu: Introduce nbd-server-start command
qemu: Introduce nbd-server-add command
qemu: Introduce nbd-server-stop command
qemu_migration: Introduce qemuMigrationStartNBDServer
qemu_migration: Move port allocation to a separate func
qemu_migration: Implement qemuMigrationStartNBDServer()
qemu_migration: Implement qemuMigrationDriveMirror
qemu_migration: Check size prerequisites
qemu_migration: Stop NBD server at Finish phase
src/qemu/qemu_capabilities.c | 3 +
src/qemu/qemu_capabilities.h | 1 +
src/qemu/qemu_driver.c | 8 +-
src/qemu/qemu_migration.c | 620 +++++++++++++++++++++++++++++++++++++++---
src/qemu/qemu_migration.h | 6 +-
src/qemu/qemu_monitor.c | 63 +++++
src/qemu/qemu_monitor.h | 7 +
src/qemu/qemu_monitor_json.c | 95 +++++++
src/qemu/qemu_monitor_json.h | 7 +
9 files changed, 772 insertions(+), 38 deletions(-)
--
1.7.8.6
11 years, 11 months
[libvirt] [PATCH] BZ 657918 Default iptables setup in libvirt breaks mDNS
by Brian J. Murrell
Hi,
Per the request on https://bugzilla.redhat.com/show_bug.cgi?id=657918
please find attached a patch that should address the issue.
I'm not subscribed to this list though (I know, it's pretty rude, but
my e-mail traffic is already too heavy to add another list to it), so
if you could either CC me on any follow-up or just move followups to
the BZ ticket where the patch also appears, that would be great.
Cheers,
b.
--- src/network/bridge_driver.c.orig 2012-10-27 16:56:23.000000000 -0400
+++ src/network/bridge_driver.c 2012-12-11 15:49:13.937133883 -0500
@@ -1301,9 +1301,10 @@
*
* We need to end up with 3 rules in the table in this order
*
- * 1. protocol=tcp with sport mapping restriction
- * 2. protocol=udp with sport mapping restriction
- * 3. generic any protocol
+ * 1. multicast is exempted
+ * 2. protocol=tcp with sport mapping restriction
+ * 3. protocol=udp with sport mapping restriction
+ * 4. generic any protocol
*
* The sport mappings are required, because default IPtables
* MASQUERADE maintain port numbers unchanged where possible.
@@ -1361,8 +1362,21 @@
goto masqerr5;
}
+ /* exempt multicast traffic */
+ if (iptablesAddForwardMasqueradeExempt(driver->iptables) < 0) {
+ virReportError(VIR_ERR_SYSTEM_ERROR,
+ _("failed to add iptables rule to exempt multicast traffic from masquerading"));
+ goto masqerr6;
+ }
+
return 0;
+ masqerr6:
+ iptablesRemoveForwardMasquerade(driver->iptables,
+ &ipdef->address,
+ prefix,
+ forwardIf,
+ "tcp");
masqerr5:
iptablesRemoveForwardMasquerade(driver->iptables,
&ipdef->address,
--- src/util/iptables.c.orig 2012-10-27 16:56:23.000000000 -0400
+++ src/util/iptables.c 2012-12-11 15:53:28.715044866 -0500
@@ -858,6 +858,26 @@
}
/**
+ * iptablesAddForwardMasqueradeExempt:
+ * @ctx: pointer to the IP table context
+ *
+ * Add rules to the IP table context to exempt masquerading
+ * for multicast networks
+ *
+ * Returns 0 in case of success or an error code otherwise
+ */
+int
+iptablesAddForwardMasqueradeExempt(iptablesContext *ctx)
+{
+ return iptablesAddRemoveRule(ctx->nat_postrouting,
+ AF_INET,
+ ADD,
+ "--destination", "224.0.0.0/4",
+ "--jump", "RETURN",
+ NULL);
+}
+
+/**
* iptablesAddForwardMasquerade:
* @ctx: pointer to the IP table context
* @network: the source network name
--- src/util/iptables.h.orig 2012-10-27 16:56:23.000000000 -0400
+++ src/util/iptables.h 2012-12-11 15:57:03.284144679 -0500
@@ -101,6 +101,7 @@
int family,
const char *iface);
+int iptablesAddForwardMasqueradeExempt (iptablesContext *ctx);
int iptablesAddForwardMasquerade (iptablesContext *ctx,
virSocketAddr *netaddr,
unsigned int prefix,
--- src/libvirt_private.syms.orig 2012-12-11 15:46:11.141932324 -0500
+++ src/libvirt_private.syms 2012-12-11 15:58:11.715865516 -0500
@@ -681,6 +681,7 @@
iptablesAddForwardAllowOut;
iptablesAddForwardAllowRelatedIn;
iptablesAddForwardMasquerade;
+iptablesAddForwardMasqueradeExempt;
iptablesAddForwardRejectIn;
iptablesAddForwardRejectOut;
iptablesAddOutputFixUdpChecksum;
11 years, 11 months
Re: [libvirt] Memory free in libvirt JNA
by Benjamin Wang (gendwang)
Hi,
I wrote a code to verify the memory leak problem as following.
C code in so:
void checkJNAMemLeak1(int **head, int *length)
{
long i = 0;
*head = (int *)malloc(sizeof(int) * 100000000);
for(i=0; i<100000000; i++)
{
(*head)[i] = 1;
}
*length = 100000000;
}
Java code:
public static void testJNAMemLeak1()
{
PointerByReference head = new PointerByReference();
IntByReference length = new IntByReference();
while(true)
{
libben.checkJNAMemLeak1(head, length);
System.out.println(length.getValue());
sleep(1);
}
}
When we check memory by top command, the virt and res will increase very quickly. When we check with jconsole, there is no memory in Java heap. Even I execute GC manually by jconsole. Nothing happen.
If I change java code as following:
public static void testJNAMemLeak1()
{
PointerByReference head = new PointerByReference();
IntByReference length = new IntByReference();
while(true)
{
libben.checkJNAMemLeak1(head, length);
System.out.println(length.getValue());
sleep(1);
libc.free(head.getValue());
}
}
public static void testJNAMemLeak1()
{
PointerByReference head = new PointerByReference();
IntByReference length = new IntByReference();
while(true)
{
libben.checkJNAMemLeak1(head, length);
System.out.println(length.getValue());
sleep(1);
libc.free(head.getValue());
}
}
Then everything works well. The virt and res will not increase.
I think we must provide the free functions for all the memory allocated by libvirt.
B.R.
Benjamin Wang
-----Original Message-----
From: Benjamin Wang (gendwang)
Sent: 2012年9月7日 15:22
To: libvir-list(a)redhat.com
Cc: 'veillard(a)redhat.com'; Yang Zhou (yangzho)
Subject: RE: Memory free in libvirt JNA
Hi,
Overview Part of JNA API describes as following:
1. Description1:
If the native method returns char* and actually allocates memory, a return type of Pointer should be used to avoid leaking the memory. It is then up to you to take the necessary steps to free the allocated memory.
2. Description2:
Declare the method as returning a Structure of the appropriate type, then invoke Structure.toArray(int) to convert to an array of initialized structures of the appropriate size. Note that your Structure class must have a no-args constructor, and you are responsible for freeing the returned memory if applicable in whatever way is appropriate for the called function.
And the example code shows as following:
// Original C code
struct Display* get_displays(int* pcount); void free_displays(struct Display* displays);
// Equivalent JNA mapping
Display get_displays(IntByReference pcount); void free_displays(Display[] displays); ...
IntByReference pcount = new IntByReference(); Display d = lib.get_displays(pcount); Display[] displays = (Display[])d.toArray(pcount.getValue());
...
lib.free_displays(displays);
That's to say. All the memory allocated by native code must be freed explicitly in JNA part. We must add some free memory methods to support the memory-freeing.
Any comments?
B.R.
Benjamin Wang
-----Original Message-----
From: Daniel Veillard [mailto:veillard@redhat.com]
Sent: 2012年8月20日 14:25
To: Benjamin Wang (gendwang)
Cc: stoty(a)tvnet.hu; Daniel.Schwager(a)dtnet.de
Subject: Re: Memory free in libvirt JNA
On Mon, Aug 20, 2012 at 05:15:45AM +0000, Benjamin Wang (gendwang) wrote:
> Hi Veillard,
> Thanks for your reply. I checked the current Libvirt-JNA
> implementation. I find that a method named "free" defined in Domain
> class which is used to free the domain object. If this is mandatory, that's to say, we should a lot of methods into the current Libvirt-jna implementation to free the memory which is allocated by libvirt API. Please correct me!
As far as I understat free() is aliased as finalize() on that object so the java runtime will call free() automatically on garbage collection. I'm not a java expert, check some Java litterature for more details about how this is done and the cases where
free() might be better called directly.
Daniel
--
Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/
daniel(a)veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/
11 years, 11 months