[libvirt] [PATCH] qemu: Capitalize "storage" in qemuDomainAttachUSBMassStorageDevice()
by Andrea Bolognani
---
src/qemu/qemu_hotplug.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 94ebe35..3562de6 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -680,7 +680,7 @@ qemuDomainAttachSCSIDisk(virConnectPtr conn,
static int
-qemuDomainAttachUSBMassstorageDevice(virConnectPtr conn,
+qemuDomainAttachUSBMassStorageDevice(virConnectPtr conn,
virQEMUDriverPtr driver,
virDomainObjPtr vm,
virDomainDiskDefPtr disk)
@@ -823,7 +823,7 @@ qemuDomainAttachDeviceDiskLive(virConnectPtr conn,
_("disk device='lun' is not supported for usb bus"));
break;
}
- ret = qemuDomainAttachUSBMassstorageDevice(conn, driver, vm,
+ ret = qemuDomainAttachUSBMassStorageDevice(conn, driver, vm,
disk);
} else if (disk->bus == VIR_DOMAIN_DISK_BUS_VIRTIO) {
ret = qemuDomainAttachVirtioDiskDevice(conn, driver, vm, disk);
--
2.4.2
9 years, 5 months
[libvirt] Qemu-Libgfapi: periodical shutdown of virtual machines.
by Igor Yakovlev
Hello,
Would you so kind to help me with my problem concerning libgfapi.
My host operating system is Ubuntu 14.04 LTS, version of glusterfs is
3.6.2, and version of qemu is 2.0.0. We use libfgapi library to connect to glusterfs.
In our environment virtual machines sometimes go to power-off
state 'Powered Off'(Shutdown) with ERROR in /var/log/syslog like:
kernel: [5346607.988173] qemu-system-x86[29564]: segfault at 128 ip
00007f930a90b48c sp 00007f931296fd70 error 4 in
qemu-system-x86_64[7f930a57f000+4b1000]
Please help me to understand possible reasons of the qemu-system segfault.
Maybe glusterfs tuning is required or tuning of libvirt.
Do you have any ideas?...
Best regards,
Igor.
9 years, 5 months
[libvirt] [PATCH v4] parallels: add block device statistics to driver
by Nikolay Shirokovskiy
Statistics provided through PCS SDK. As we have only async interface in SDK we
need to be subscribed to statistics in order to get it. Trivial solution on
every stat request to subscribe, wait event and then unsubscribe will lead to
significant delays in case of a number of successive requests, as the event
will be delivered on next PCS server notify cycle. On the other hand we don't
want to keep unnesessary subscribtion. So we take an hibrid solution to
subcsribe on first request and then keep a subscription while requests are
active. We populate cache of statistics on subscribtion events and use this
cache to serve libvirts requests.
* Cache details.
Cache is just handle to last arrived event, we call this cache
as if this handle is valid it is used to serve synchronous
statistics requests. We use number of successive events count
to detect that user lost interest to statistics. We reset this
count to 0 on every request. If more than PARALLELS_STATISTICS_DROP_COUNT
successive events arrive we unsubscribe. Special value of -1
of this counter is used to differentiate between subscribed/unsubscribed state
to protect from delayed events.
Values of PARALLELS_STATISTICS_DROP_COUNT and PARALLELS_STATISTICS_TIMEOUT are
just drop-ins, choosen without special consideration.
* Thread safety issues
Use parallelsDomObjFromDomainRef in parallelsDomainBlockStats as
we could wait on domain lock down on stack in prlsdkGetStatsParam
and if we won't keep reference we could get dangling pointer
on return from wait.
Signed-off-by: Nikolay Shirokovskiy <nshirokovskiy(a)parallels.com>
---
src/parallels/parallels_driver.c | 106 ++++++++++++++++++++
src/parallels/parallels_sdk.c | 200 +++++++++++++++++++++++++++++++++++++-
src/parallels/parallels_sdk.h | 2 +
src/parallels/parallels_utils.c | 28 ++++++
src/parallels/parallels_utils.h | 18 ++++
5 files changed, 350 insertions(+), 4 deletions(-)
diff --git a/src/parallels/parallels_driver.c b/src/parallels/parallels_driver.c
index 4b87213..33c112e 100644
--- a/src/parallels/parallels_driver.c
+++ b/src/parallels/parallels_driver.c
@@ -51,6 +51,7 @@
#include "nodeinfo.h"
#include "virstring.h"
#include "cpu/cpu.h"
+#include "virtypedparam.h"
#include "parallels_driver.h"
#include "parallels_utils.h"
@@ -1179,6 +1180,109 @@ parallelsDomainGetMaxMemory(virDomainPtr domain)
return ret;
}
+static int
+parallelsDomainBlockStats(virDomainPtr domain, const char *path,
+ virDomainBlockStatsPtr stats)
+{
+ virDomainObjPtr dom = NULL;
+ int ret = -1;
+ size_t i;
+ int idx;
+
+ if (!(dom = parallelsDomObjFromDomainRef(domain)))
+ return -1;
+
+ if (*path) {
+ if ((idx = virDomainDiskIndexByName(dom->def, path, false)) < 0) {
+ virReportError(VIR_ERR_INVALID_ARG, _("invalid path: %s"), path);
+ goto cleanup;
+ }
+ if (prlsdkGetBlockStats(dom, dom->def->disks[idx], stats) < 0)
+ goto cleanup;
+ } else {
+ virDomainBlockStatsStruct s;
+
+#define PARALLELS_ZERO_STATS(VAR, TYPE, NAME) \
+ stats->VAR = 0;
+
+ PARALLELS_BLOCK_STATS_FOREACH(PARALLELS_ZERO_STATS)
+
+#undef PARALLELS_ZERO_STATS
+
+ for (i = 0; i < dom->def->ndisks; i++) {
+ if (prlsdkGetBlockStats(dom, dom->def->disks[i], &s) < 0)
+ goto cleanup;
+
+#define PARALLELS_SUM_STATS(VAR, TYPE, NAME) \
+ if (s.VAR != -1) \
+ stats->VAR += s.VAR;
+
+ PARALLELS_BLOCK_STATS_FOREACH(PARALLELS_SUM_STATS)
+
+#undef PARALLELS_SUM_STATS
+ }
+ }
+ stats->errs = -1;
+ ret = 0;
+
+ cleanup:
+ if (dom)
+ virDomainObjEndAPI(&dom);
+
+ return ret;
+}
+
+static int
+parallelsDomainBlockStatsFlags(virDomainPtr domain,
+ const char *path,
+ virTypedParameterPtr params,
+ int *nparams,
+ unsigned int flags)
+{
+ virDomainBlockStatsStruct stats;
+ int ret = -1;
+ size_t i;
+
+ virCheckFlags(VIR_TYPED_PARAM_STRING_OKAY, -1);
+ /* We don't return strings, and thus trivially support this flag. */
+ flags &= ~VIR_TYPED_PARAM_STRING_OKAY;
+
+ if (parallelsDomainBlockStats(domain, path, &stats) < 0)
+ goto cleanup;
+
+ if (*nparams == 0) {
+#define PARALLELS_COUNT_STATS(VAR, TYPE, NAME) \
+ if ((stats.VAR) != -1) \
+ ++*nparams;
+
+ PARALLELS_BLOCK_STATS_FOREACH(PARALLELS_COUNT_STATS)
+
+#undef PARALLELS_COUNT_STATS
+ ret = 0;
+ goto cleanup;
+ }
+
+ i = 0;
+#define PARALLELS_BLOCK_STATS_ASSIGN_PARAM(VAR, TYPE, NAME) \
+ if (i < *nparams && (stats.VAR) != -1) { \
+ if (virTypedParameterAssign(params + i, TYPE, \
+ VIR_TYPED_PARAM_LLONG, (stats.VAR)) < 0) \
+ goto cleanup; \
+ i++; \
+ }
+
+ PARALLELS_BLOCK_STATS_FOREACH(PARALLELS_BLOCK_STATS_ASSIGN_PARAM)
+
+#undef PARALLELS_BLOCK_STATS_ASSIGN_PARAM
+
+ *nparams = i;
+ ret = 0;
+
+ cleanup:
+ return ret;
+}
+
+
static virHypervisorDriver parallelsDriver = {
.name = "Parallels",
.connectOpen = parallelsConnectOpen, /* 0.10.0 */
@@ -1228,6 +1332,8 @@ static virHypervisorDriver parallelsDriver = {
.domainManagedSave = parallelsDomainManagedSave, /* 1.2.14 */
.domainManagedSaveRemove = parallelsDomainManagedSaveRemove, /* 1.2.14 */
.domainGetMaxMemory = parallelsDomainGetMaxMemory, /* 1.2.15 */
+ .domainBlockStats = parallelsDomainBlockStats, /* 1.2.17 */
+ .domainBlockStatsFlags = parallelsDomainBlockStatsFlags, /* 1.2.17 */
};
static virConnectDriver parallelsConnectDriver = {
diff --git a/src/parallels/parallels_sdk.c b/src/parallels/parallels_sdk.c
index 6d63759..00e51f4 100644
--- a/src/parallels/parallels_sdk.c
+++ b/src/parallels/parallels_sdk.c
@@ -21,6 +21,7 @@
*/
#include <config.h>
+#include <stdarg.h>
#include "virerror.h"
#include "viralloc.h"
@@ -29,6 +30,7 @@
#include "virlog.h"
#include "datatypes.h"
#include "domain_conf.h"
+#include "virtime.h"
#include "parallels_sdk.h"
@@ -407,6 +409,8 @@ prlsdkDomObjFreePrivate(void *p)
return;
PrlHandle_Free(pdom->sdkdom);
+ PrlHandle_Free(pdom->cache.stats);
+ virCondDestroy(&pdom->cache.cond);
VIR_FREE(pdom->uuid);
VIR_FREE(pdom->home);
VIR_FREE(p);
@@ -1260,6 +1264,13 @@ prlsdkLoadDomain(parallelsConnPtr privconn,
* to NULL temporarily */
pdom->uuid = NULL;
+ pdom->cache.stats = PRL_INVALID_HANDLE;
+ pdom->cache.count = -1;
+ if (virCondInit(&pdom->cache.cond) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("cannot initialize condition"));
+ goto error;
+ }
+
if (prlsdkGetDomainIds(sdkdom, &def->name, def->uuid) < 0)
goto error;
@@ -1611,6 +1622,51 @@ prlsdkHandleVmRemovedEvent(parallelsConnPtr privconn,
return;
}
+#define PARALLELS_STATISTICS_DROP_COUNT 3
+
+static PRL_RESULT
+prlsdkHandlePerfEvent(parallelsConnPtr privconn,
+ PRL_HANDLE event,
+ unsigned char *uuid)
+{
+ virDomainObjPtr dom = NULL;
+ parallelsDomObjPtr privdom = NULL;
+ PRL_HANDLE job = PRL_INVALID_HANDLE;
+
+ dom = virDomainObjListFindByUUID(privconn->domains, uuid);
+ if (dom == NULL)
+ goto cleanup;
+ privdom = dom->privateData;
+
+ // delayed event after unsubscribe
+ if (privdom->cache.count == -1)
+ goto cleanup;
+
+ PrlHandle_Free(privdom->cache.stats);
+ privdom->cache.stats = PRL_INVALID_HANDLE;
+
+ if (privdom->cache.count > PARALLELS_STATISTICS_DROP_COUNT) {
+ job = PrlVm_UnsubscribeFromPerfStats(privdom->sdkdom);
+ if (PRL_FAILED(waitJob(job)))
+ goto cleanup;
+ // change state to unsubscribed
+ privdom->cache.count = -1;
+ } else {
+ ++privdom->cache.count;
+ privdom->cache.stats = event;
+ // thus we get own of event handle
+ event = PRL_INVALID_HANDLE;
+ virCondSignal(&privdom->cache.cond);
+ }
+
+ cleanup:
+ PrlHandle_Free(event);
+ if (dom)
+ virObjectUnlock(dom);
+
+ return PRL_ERR_SUCCESS;
+}
+
static void
prlsdkHandleVmEvent(parallelsConnPtr privconn, PRL_HANDLE prlEvent)
{
@@ -1621,13 +1677,13 @@ prlsdkHandleVmEvent(parallelsConnPtr privconn, PRL_HANDLE prlEvent)
PRL_EVENT_TYPE prlEventType;
pret = PrlEvent_GetType(prlEvent, &prlEventType);
- prlsdkCheckRetGoto(pret, error);
+ prlsdkCheckRetGoto(pret, cleanup);
pret = PrlEvent_GetIssuerId(prlEvent, uuidstr, &bufsize);
- prlsdkCheckRetGoto(pret, error);
+ prlsdkCheckRetGoto(pret, cleanup);
if (prlsdkUUIDParse(uuidstr, uuid) < 0)
- return;
+ goto cleanup;
switch (prlEventType) {
case PET_DSP_EVT_VM_STATE_CHANGED:
@@ -1644,12 +1700,18 @@ prlsdkHandleVmEvent(parallelsConnPtr privconn, PRL_HANDLE prlEvent)
case PET_DSP_EVT_VM_UNREGISTERED:
prlsdkHandleVmRemovedEvent(privconn, uuid);
break;
+ case PET_DSP_EVT_VM_PERFSTATS:
+ prlsdkHandlePerfEvent(privconn, prlEvent, uuid);
+ // above function takes own of event
+ prlEvent = PRL_INVALID_HANDLE;
+ break;
default:
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Can't handle event of type %d"), prlEventType);
}
- error:
+ cleanup:
+ PrlHandle_Free(prlEvent);
return;
}
@@ -1677,6 +1739,8 @@ prlsdkEventsHandler(PRL_HANDLE prlEvent, PRL_VOID_PTR opaque)
switch (prlIssuerType) {
case PIE_VIRTUAL_MACHINE:
prlsdkHandleVmEvent(privconn, prlEvent);
+ // above function takes own of event
+ prlEvent = PRL_INVALID_HANDLE;
break;
default:
VIR_DEBUG("Skipping event of issuer type %d", prlIssuerType);
@@ -1687,6 +1751,7 @@ prlsdkEventsHandler(PRL_HANDLE prlEvent, PRL_VOID_PTR opaque)
return PRL_ERR_SUCCESS;
}
+
int prlsdkSubscribeToPCSEvents(parallelsConnPtr privconn)
{
PRL_RESULT pret = PRL_ERR_UNINITIALIZED;
@@ -3423,3 +3488,130 @@ prlsdkDomainManagedSaveRemove(virDomainObjPtr dom)
return 0;
}
+
+static int
+prlsdkExtractStatsParam(PRL_HANDLE sdkstats, const char *name, long long *val)
+{
+ PRL_HANDLE param = PRL_INVALID_HANDLE;
+ PRL_RESULT pret;
+ PRL_INT64 pval = 0;
+ int ret = -1;
+
+ pret = PrlEvent_GetParamByName(sdkstats, name, ¶m);
+ if (pret == PRL_ERR_NO_DATA) {
+ *val = -1;
+ ret = 0;
+ goto cleanup;
+ } else if (PRL_FAILED(pret)) {
+ logPrlError(pret);
+ goto cleanup;
+ }
+ pret = PrlEvtPrm_ToInt64(param, &pval);
+ prlsdkCheckRetGoto(pret, cleanup);
+
+ *val = pval;
+ ret = 0;
+
+ cleanup:
+ PrlHandle_Free(param);
+ return ret;
+}
+
+#define PARALLELS_STATISTICS_TIMEOUT (60 * 1000)
+
+static int
+prlsdkGetStatsParam(virDomainObjPtr dom, const char *name, long long *val)
+{
+ parallelsDomObjPtr privdom = dom->privateData;
+ PRL_HANDLE job = PRL_INVALID_HANDLE;
+ unsigned long long now;
+
+ if (privdom->cache.stats != PRL_INVALID_HANDLE) {
+ // reset count to keep subscribtion
+ privdom->cache.count = 0;
+ return prlsdkExtractStatsParam(privdom->cache.stats, name, val);
+ }
+
+ if (privdom->cache.count == -1) {
+ job = PrlVm_SubscribeToPerfStats(privdom->sdkdom, NULL);
+ if (PRL_FAILED(waitJob(job)))
+ goto error;
+ }
+
+ // change state to subscribed in case of unsubscribed
+ // or reset count so we stop unsubscribe attempts
+ privdom->cache.count = 0;
+
+ if (virTimeMillisNow(&now) < 0) {
+ virReportSystemError(errno, "%s", _("Unable to get current time"));
+ goto error;
+ }
+
+ while (privdom->cache.stats == PRL_INVALID_HANDLE) {
+ if (virCondWaitUntil(&privdom->cache.cond, &dom->parent.lock,
+ now + PARALLELS_STATISTICS_TIMEOUT) < 0) {
+ if (errno == ETIMEDOUT) {
+ virReportError(VIR_ERR_OPERATION_TIMEOUT, "%s",
+ _("Timeout on waiting statistics event."));
+ goto error;
+ } else {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Unable to wait on monitor condition"));
+ goto error;
+ }
+ }
+ }
+
+ return prlsdkExtractStatsParam(privdom->cache.stats, name, val);
+ error:
+ return -1;
+}
+
+int
+prlsdkGetBlockStats(virDomainObjPtr dom, virDomainDiskDefPtr disk, virDomainBlockStatsPtr stats)
+{
+ virDomainDeviceDriveAddressPtr address;
+ int idx;
+ const char *prefix;
+ int ret = -1;
+ char *name = NULL;
+
+ address = &disk->info.addr.drive;
+ switch (disk->bus) {
+ case VIR_DOMAIN_DISK_BUS_IDE:
+ prefix = "ide";
+ idx = address->bus * 2 + address->unit;
+ break;
+ case VIR_DOMAIN_DISK_BUS_SATA:
+ prefix = "sata";
+ idx = address->unit;
+ break;
+ case VIR_DOMAIN_DISK_BUS_SCSI:
+ prefix = "scsi";
+ idx = address->unit;
+ break;
+ default:
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Unknown disk bus: %X"), disk->bus);
+ goto cleanup;
+ }
+
+
+#define PRLSDK_GET_STAT_PARAM(VAL, TYPE, NAME) \
+ if (virAsprintf(&name, "devices.%s%d.%s", prefix, idx, NAME) < 0) \
+ goto cleanup; \
+ if (prlsdkGetStatsParam(dom, name, &stats->VAL) < 0) \
+ goto cleanup; \
+ VIR_FREE(name);
+
+ PARALLELS_BLOCK_STATS_FOREACH(PRLSDK_GET_STAT_PARAM)
+
+#undef PRLSDK_GET_STAT_PARAM
+
+ ret = 0;
+
+ cleanup:
+
+ VIR_FREE(name);
+ return ret;
+}
diff --git a/src/parallels/parallels_sdk.h b/src/parallels/parallels_sdk.h
index 3f17fc8..afa6745 100644
--- a/src/parallels/parallels_sdk.h
+++ b/src/parallels/parallels_sdk.h
@@ -64,3 +64,5 @@ int
prlsdkAttachVolume(virDomainObjPtr dom, virDomainDiskDefPtr disk);
int
prlsdkDetachVolume(virDomainObjPtr dom, virDomainDiskDefPtr disk);
+int
+prlsdkGetBlockStats(virDomainObjPtr dom, virDomainDiskDefPtr disk, virDomainBlockStatsPtr stats);
diff --git a/src/parallels/parallels_utils.c b/src/parallels/parallels_utils.c
index ff9d47d..540986b 100644
--- a/src/parallels/parallels_utils.c
+++ b/src/parallels/parallels_utils.c
@@ -64,6 +64,34 @@ parallelsDomObjFromDomain(virDomainPtr domain)
}
+/**
+ * parallelsDomObjFromDomainRef:
+ * @domain: Domain pointer that has to be looked up
+ *
+ * This function looks up @domain and returns the appropriate virDomainObjPtr
+ * that has to be released by calling virDomainObjEndAPI().
+ *
+ * Returns the domain object with incremented reference counter which is locked
+ * on success, NULL otherwise.
+ */
+virDomainObjPtr
+parallelsDomObjFromDomainRef(virDomainPtr domain)
+{
+ virDomainObjPtr vm;
+ parallelsConnPtr privconn = domain->conn->privateData;
+ char uuidstr[VIR_UUID_STRING_BUFLEN];
+
+ vm = virDomainObjListFindByUUIDRef(privconn->domains, domain->uuid);
+ if (!vm) {
+ virUUIDFormat(domain->uuid, uuidstr);
+ virReportError(VIR_ERR_NO_DOMAIN,
+ _("no domain with matching uuid '%s' (%s)"),
+ uuidstr, domain->name);
+ return NULL;
+ }
+
+ return vm;
+}
static int
parallelsDoCmdRun(char **outbuf, const char *binary, va_list list)
diff --git a/src/parallels/parallels_utils.h b/src/parallels/parallels_utils.h
index 2d1d405..cdf6082 100644
--- a/src/parallels/parallels_utils.h
+++ b/src/parallels/parallels_utils.h
@@ -73,11 +73,22 @@ struct _parallelsConn {
typedef struct _parallelsConn parallelsConn;
typedef struct _parallelsConn *parallelsConnPtr;
+struct _parallelsContersCache {
+ PRL_HANDLE stats;
+ virCond cond;
+ // -1 - unsubscribed
+ // > -1 - subscribed
+ int count;
+};
+
+typedef struct _parallelsContersCache parallelsContersCache;
+
struct parallelsDomObj {
int id;
char *uuid;
char *home;
PRL_HANDLE sdkdom;
+ parallelsContersCache cache;
};
typedef struct parallelsDomObj *parallelsDomObjPtr;
@@ -91,6 +102,7 @@ int parallelsNetworkClose(virConnectPtr conn);
extern virNetworkDriver parallelsNetworkDriver;
virDomainObjPtr parallelsDomObjFromDomain(virDomainPtr domain);
+virDomainObjPtr parallelsDomObjFromDomainRef(virDomainPtr domain);
virJSONValuePtr parallelsParseOutput(const char *binary, ...)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_SENTINEL;
@@ -106,4 +118,10 @@ virStorageVolPtr parallelsStorageVolLookupByPathLocked(virConnectPtr conn,
int parallelsStorageVolDefRemove(virStoragePoolObjPtr privpool,
virStorageVolDefPtr privvol);
+#define PARALLELS_BLOCK_STATS_FOREACH(OP) \
+ OP(rd_req, VIR_DOMAIN_BLOCK_STATS_READ_REQ, "read_requests") \
+ OP(rd_bytes, VIR_DOMAIN_BLOCK_STATS_READ_BYTES, "read_total") \
+ OP(wr_req, VIR_DOMAIN_BLOCK_STATS_WRITE_REQ, "write_requests") \
+ OP(wr_bytes, VIR_DOMAIN_BLOCK_STATS_WRITE_BYTES, "write_total")
+
#endif
--
1.7.1
9 years, 5 months
[libvirt] [PATCH 0/3] qemu: Allow arm 32-on-64 KVM
by Cole Robinson
qemu 2.3.0 added support for enabling armv7l VMs to run on aarch64 hosts
with KVM. First patch handles the special command line bit, last two
patches are about advertising things in virsh capabilities.
After these patches, 'virt-install --arch armv7l ...' on an aarch64
host with new enough qemu will automatically use KVM and generate a
working config.
Cole Robinson (3):
qemu: command: Support arm 32-on-64 KVM with -cpu aarch64=off
qemu: caps: qemu-system-aarch64 supports armv7l
qemu: caps: Advertise arm 32-on-64 KVM option
src/qemu/qemu_capabilities.c | 57 ++++++++++++++--------
src/qemu/qemu_capabilities.h | 1 +
src/qemu/qemu_command.c | 13 +++++
.../qemuxml2argv-aarch64-kvm-32-on-64.args | 10 ++++
.../qemuxml2argv-aarch64-kvm-32-on-64.xml | 35 +++++++++++++
tests/qemuxml2argvtest.c | 9 ++++
6 files changed, 105 insertions(+), 20 deletions(-)
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-aarch64-kvm-32-on-64.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-aarch64-kvm-32-on-64.xml
--
2.4.1
9 years, 5 months
[libvirt] [PATCH] parallels: return only success from PCS event handler
by Nikolay Shirokovskiy
2 reasons to to this.
1. PCS SDK really don't care of handler return value.
2. It hard to imagine how notifier can handle
subscriber failures. Even if there are some situations
we probably will use some special error codes and
not just throw error codes we get from SDK itself.
Signed-off-by: Nikolay Shirokovskiy <nshirokovskiy(a)parallels.com>
---
src/parallels/parallels_sdk.c | 121 ++++++++++++++++-------------------------
1 files changed, 47 insertions(+), 74 deletions(-)
diff --git a/src/parallels/parallels_sdk.c b/src/parallels/parallels_sdk.c
index d5a9790..6d63759 100644
--- a/src/parallels/parallels_sdk.c
+++ b/src/parallels/parallels_sdk.c
@@ -1516,7 +1516,7 @@ prlsdkNewStateToEvent(VIRTUAL_MACHINE_STATE domainState,
}
}
-static PRL_RESULT
+static void
prlsdkHandleVmStateEvent(parallelsConnPtr privconn,
PRL_HANDLE prlEvent,
unsigned char *uuid)
@@ -1529,18 +1529,16 @@ prlsdkHandleVmStateEvent(parallelsConnPtr privconn,
virDomainEventType lvEventType = 0;
int lvEventTypeDetails = 0;
+ dom = virDomainObjListFindByUUID(privconn->domains, uuid);
+ if (dom == NULL)
+ return;
+
pret = PrlEvent_GetParamByName(prlEvent, "vminfo_vm_state", &eventParam);
prlsdkCheckRetGoto(pret, cleanup);
pret = PrlEvtPrm_ToInt32(eventParam, &domainState);
prlsdkCheckRetGoto(pret, cleanup);
- dom = virDomainObjListFindByUUID(privconn->domains, uuid);
- if (dom == NULL) {
- pret = PRL_ERR_VM_UUID_NOT_FOUND;
- goto cleanup;
- }
-
pdom = dom->privateData;
if (prlsdkConvertDomainState(domainState, pdom->id, dom) < 0)
goto cleanup;
@@ -1549,96 +1547,74 @@ prlsdkHandleVmStateEvent(parallelsConnPtr privconn,
&lvEventType,
&lvEventTypeDetails);
- if (prlsdkSendEvent(privconn, dom, lvEventType, lvEventTypeDetails) < 0) {
- pret = PRL_ERR_OUT_OF_MEMORY;
- goto cleanup;
- }
+ prlsdkSendEvent(privconn, dom, lvEventType, lvEventTypeDetails);
cleanup:
- if (dom)
- virObjectUnlock(dom);
- return pret;
+ virObjectUnlock(dom);
+ return;
}
-static PRL_RESULT
+static void
prlsdkHandleVmConfigEvent(parallelsConnPtr privconn,
unsigned char *uuid)
{
- PRL_RESULT pret = PRL_ERR_FAILURE;
virDomainObjPtr dom = NULL;
dom = virDomainObjListFindByUUID(privconn->domains, uuid);
- if (dom == NULL) {
- pret = PRL_ERR_VM_UUID_NOT_FOUND;
- goto cleanup;
- }
+ if (dom == NULL)
+ return;
if (prlsdkUpdateDomain(privconn, dom) < 0)
goto cleanup;
- if (prlsdkSendEvent(privconn, dom, VIR_DOMAIN_EVENT_DEFINED,
- VIR_DOMAIN_EVENT_DEFINED_UPDATED) < 0) {
- pret = PRL_ERR_OUT_OF_MEMORY;
- goto cleanup;
- }
+ prlsdkSendEvent(privconn, dom, VIR_DOMAIN_EVENT_DEFINED,
+ VIR_DOMAIN_EVENT_DEFINED_UPDATED);
- pret = PRL_ERR_SUCCESS;
cleanup:
- if (dom)
- virObjectUnlock(dom);
- return pret;
+ virObjectUnlock(dom);
+ return;
}
-static PRL_RESULT
+static void
prlsdkHandleVmAddedEvent(parallelsConnPtr privconn,
unsigned char *uuid)
{
- PRL_RESULT pret;
virDomainObjPtr dom = NULL;
dom = prlsdkAddDomain(privconn, uuid);
- if (!dom)
- return PRL_ERR_FAILURE;
+ if (dom == NULL)
+ return;
- if (prlsdkSendEvent(privconn, dom, VIR_DOMAIN_EVENT_DEFINED,
- VIR_DOMAIN_EVENT_DEFINED_ADDED) < 0) {
- pret = PRL_ERR_OUT_OF_MEMORY;
- goto cleanup;
- }
+ prlsdkSendEvent(privconn, dom, VIR_DOMAIN_EVENT_DEFINED,
+ VIR_DOMAIN_EVENT_DEFINED_ADDED);
- pret = PRL_ERR_SUCCESS;
- cleanup:
- if (dom)
- virObjectUnlock(dom);
- return pret;
+ virObjectUnlock(dom);
+ return;
}
-static PRL_RESULT
+static void
prlsdkHandleVmRemovedEvent(parallelsConnPtr privconn,
unsigned char *uuid)
{
virDomainObjPtr dom = NULL;
- PRL_RESULT pret = PRL_ERR_SUCCESS;
dom = virDomainObjListFindByUUID(privconn->domains, uuid);
- if (dom == NULL) {
- /* domain was removed from the list from the libvirt
- * API function in current connection */
- return PRL_ERR_SUCCESS;
- }
+ /* domain was removed from the list from the libvirt
+ * API function in current connection */
+ if (dom == NULL)
+ return;
- if (prlsdkSendEvent(privconn, dom, VIR_DOMAIN_EVENT_UNDEFINED,
- VIR_DOMAIN_EVENT_UNDEFINED_REMOVED) < 0)
- pret = PRL_ERR_OUT_OF_MEMORY;
+ prlsdkSendEvent(privconn, dom, VIR_DOMAIN_EVENT_UNDEFINED,
+ VIR_DOMAIN_EVENT_UNDEFINED_REMOVED);
virDomainObjListRemove(privconn->domains, dom);
- return pret;
+ return;
}
-static PRL_RESULT
+static void
prlsdkHandleVmEvent(parallelsConnPtr privconn, PRL_HANDLE prlEvent)
{
- PRL_RESULT pret;
+ PRL_RESULT pret = PRL_ERR_FAILURE;
char uuidstr[VIR_UUID_STRING_BUFLEN + 2];
unsigned char uuid[VIR_UUID_BUFLEN];
PRL_UINT32 bufsize = ARRAY_CARDINALITY(uuidstr);
@@ -1651,67 +1627,64 @@ prlsdkHandleVmEvent(parallelsConnPtr privconn, PRL_HANDLE prlEvent)
prlsdkCheckRetGoto(pret, error);
if (prlsdkUUIDParse(uuidstr, uuid) < 0)
- return PRL_ERR_FAILURE;
+ return;
switch (prlEventType) {
case PET_DSP_EVT_VM_STATE_CHANGED:
- return prlsdkHandleVmStateEvent(privconn, prlEvent, uuid);
+ prlsdkHandleVmStateEvent(privconn, prlEvent, uuid);
+ break;
case PET_DSP_EVT_VM_CONFIG_CHANGED:
- return prlsdkHandleVmConfigEvent(privconn, uuid);
+ prlsdkHandleVmConfigEvent(privconn, uuid);
+ break;
case PET_DSP_EVT_VM_CREATED:
case PET_DSP_EVT_VM_ADDED:
- return prlsdkHandleVmAddedEvent(privconn, uuid);
+ prlsdkHandleVmAddedEvent(privconn, uuid);
+ break;
case PET_DSP_EVT_VM_DELETED:
case PET_DSP_EVT_VM_UNREGISTERED:
- return prlsdkHandleVmRemovedEvent(privconn, uuid);
+ prlsdkHandleVmRemovedEvent(privconn, uuid);
break;
default:
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Can't handle event of type %d"), prlEventType);
- return PRL_ERR_FAILURE;
}
error:
- return PRL_ERR_FAILURE;
+ return;
}
static PRL_RESULT
prlsdkEventsHandler(PRL_HANDLE prlEvent, PRL_VOID_PTR opaque)
{
parallelsConnPtr privconn = opaque;
- PRL_RESULT pret = PRL_ERR_UNINITIALIZED;
+ PRL_RESULT pret = PRL_ERR_FAILURE;
PRL_HANDLE_TYPE handleType;
PRL_EVENT_ISSUER_TYPE prlIssuerType = PIE_UNKNOWN;
pret = PrlHandle_GetType(prlEvent, &handleType);
prlsdkCheckRetGoto(pret, cleanup);
- if (handleType != PHT_EVENT) {
- /* Currently, there is no need to handle anything but events */
- pret = PRL_ERR_SUCCESS;
+ /* Currently, there is no need to handle anything but events */
+ if (handleType != PHT_EVENT)
goto cleanup;
- }
- if (privconn == NULL) {
- pret = PRL_ERR_INVALID_ARG;
+ if (privconn == NULL)
goto cleanup;
- }
PrlEvent_GetIssuerType(prlEvent, &prlIssuerType);
prlsdkCheckRetGoto(pret, cleanup);
switch (prlIssuerType) {
case PIE_VIRTUAL_MACHINE:
- pret = prlsdkHandleVmEvent(privconn, prlEvent);
+ prlsdkHandleVmEvent(privconn, prlEvent);
break;
default:
VIR_DEBUG("Skipping event of issuer type %d", prlIssuerType);
}
- pret = PRL_ERR_SUCCESS;
cleanup:
PrlHandle_Free(prlEvent);
- return pret;
+ return PRL_ERR_SUCCESS;
}
int prlsdkSubscribeToPCSEvents(parallelsConnPtr privconn)
--
1.7.1
9 years, 5 months
[libvirt] [PATCH v2] parallels: simplify event types discrimination
by Nikolay Shirokovskiy
Use issuer type instead of event type to group
vm related events. This saves us from
explicit enumeration of all vm event types in
prlsdkHandleVmEvent.
---
src/parallels/parallels_sdk.c | 15 +++++----------
1 files changed, 5 insertions(+), 10 deletions(-)
diff --git a/src/parallels/parallels_sdk.c b/src/parallels/parallels_sdk.c
index 88ad59b..d5a9790 100644
--- a/src/parallels/parallels_sdk.c
+++ b/src/parallels/parallels_sdk.c
@@ -1681,7 +1681,7 @@ prlsdkEventsHandler(PRL_HANDLE prlEvent, PRL_VOID_PTR opaque)
parallelsConnPtr privconn = opaque;
PRL_RESULT pret = PRL_ERR_UNINITIALIZED;
PRL_HANDLE_TYPE handleType;
- PRL_EVENT_TYPE prlEventType;
+ PRL_EVENT_ISSUER_TYPE prlIssuerType = PIE_UNKNOWN;
pret = PrlHandle_GetType(prlEvent, &handleType);
prlsdkCheckRetGoto(pret, cleanup);
@@ -1697,20 +1697,15 @@ prlsdkEventsHandler(PRL_HANDLE prlEvent, PRL_VOID_PTR opaque)
goto cleanup;
}
- PrlEvent_GetType(prlEvent, &prlEventType);
+ PrlEvent_GetIssuerType(prlEvent, &prlIssuerType);
prlsdkCheckRetGoto(pret, cleanup);
- switch (prlEventType) {
- case PET_DSP_EVT_VM_STATE_CHANGED:
- case PET_DSP_EVT_VM_CONFIG_CHANGED:
- case PET_DSP_EVT_VM_CREATED:
- case PET_DSP_EVT_VM_ADDED:
- case PET_DSP_EVT_VM_DELETED:
- case PET_DSP_EVT_VM_UNREGISTERED:
+ switch (prlIssuerType) {
+ case PIE_VIRTUAL_MACHINE:
pret = prlsdkHandleVmEvent(privconn, prlEvent);
break;
default:
- VIR_DEBUG("Skipping event of type %d", prlEventType);
+ VIR_DEBUG("Skipping event of issuer type %d", prlIssuerType);
}
pret = PRL_ERR_SUCCESS;
--
1.7.1
9 years, 5 months
[libvirt] [PATCH v2 0/3] Testing of RPC JSON (de)serialization
by Daniel P. Berrange
This is a re-post of the previous patch I sent:
https://www.redhat.com/archives/libvir-list/2015-May/msg00812.html
The only change is to actually send the 2 pre-requisite patches
for it !
Daniel P. Berrange (3):
rpc: allow selection of TCP address family
rpc: add API for checking IPv4/6 availability
rpc: add testing of RPC JSON (de)serialization
daemon/libvirtd.c | 2 +
src/libvirt_remote.syms | 2 +
src/libxl/libxl_migration.c | 8 +-
src/qemu/qemu_migration.c | 4 +-
src/remote/remote_driver.c | 3 +-
src/rpc/virnetclient.c | 12 +-
src/rpc/virnetclient.h | 4 +-
src/rpc/virnetserver.c | 4 +-
src/rpc/virnetserver.h | 3 +
src/rpc/virnetserverclient.c | 13 +-
src/rpc/virnetserverservice.c | 8 +-
src/rpc/virnetserverservice.h | 1 +
src/rpc/virnetsocket.c | 74 +++++-
src/rpc/virnetsocket.h | 6 +
tests/Makefile.am | 7 +
tests/virnetserverdata/README | 14 +
.../virnetserverdata/input-data-anon-clients.json | 63 +++++
tests/virnetserverdata/input-data-initial.json | 62 +++++
.../virnetserverdata/output-data-anon-clients.json | 63 +++++
tests/virnetserverdata/output-data-initial.json | 63 +++++
tests/virnetservertest.c | 290 +++++++++++++++++++++
tests/virnetsockettest.c | 44 +---
22 files changed, 695 insertions(+), 55 deletions(-)
create mode 100644 tests/virnetserverdata/README
create mode 100644 tests/virnetserverdata/input-data-anon-clients.json
create mode 100644 tests/virnetserverdata/input-data-initial.json
create mode 100644 tests/virnetserverdata/output-data-anon-clients.json
create mode 100644 tests/virnetserverdata/output-data-initial.json
create mode 100644 tests/virnetservertest.c
--
2.4.1
9 years, 5 months
[libvirt] qemu commit 65207c59 broke libvirt's capability retrieval (apparently)
by Laszlo Ersek
Hi All,
after pulling QEMU master today, my existent libvirt guests that have the following element:
<pm>
<suspend-to-mem enabled='yes'/>
<suspend-to-disk enabled='no'/>
</pm>
started to barf the following message at me:
----------
Error starting domain: unsupported configuration: setting ACPI S3 not supported
Traceback (most recent call last):
File "/usr/share/virt-manager/virtManager/asyncjob.py", line 89, in cb_wrapper
callback(asyncjob, *args, **kwargs)
File "/usr/share/virt-manager/virtManager/asyncjob.py", line 125, in tmpcb
callback(*args, **kwargs)
File "/usr/share/virt-manager/virtManager/domain.py", line 1393, in startup
self._backend.create()
File "/usr/lib64/python2.7/site-packages/libvirt.py", line 966, in create
if ret == -1: raise libvirtError ('virDomainCreate() failed', dom=self)
libvirtError: unsupported configuration: setting ACPI S3 not supported
----------
Now, I'm using RHEL-7.1.z libvirt with bleeding edge upstream qemu, so you could say this is "kinda unsupported" :), but anyway, I reckon this might be a problem with upstream libvirt too. Sorry if it's a known problem.
I found this qemu commit, ie.
commit 65207c59d99f2260c5f1d3b9c491146616a522aa
Author: Markus Armbruster <armbru(a)redhat.com>
Date: Thu Mar 5 14:35:26 2015 +0100
monitor: Drop broken, unused asynchronous command interface
with bisection. Unfortunately, the bisection was extremely painful, because between a working version and today's pull, part of the qemu history was uncompileable. It was ultimately fixed with
commit 9e472263b07d53cb3401ee49ef1b45ef195ddb84
Author: Michael S. Tsirkin <mst(a)redhat.com>
Date: Mon Jun 1 21:03:59 2015 +0200
acpi: add missing ssdt
Luckily, that commit suggests to remove the "iasl" binary from one's system, after which I could indeed continue the bisection.
If I remove the <pm> element from the domain XML, then libvirt barfs something else:
--------------
Error starting domain: unsupported configuration: hypervisor lacks deviceboot feature
Traceback (most recent call last):
File "/usr/share/virt-manager/virtManager/asyncjob.py", line 89, in cb_wrapper
callback(asyncjob, *args, **kwargs)
File "/usr/share/virt-manager/virtManager/asyncjob.py", line 125, in tmpcb
callback(*args, **kwargs)
File "/usr/share/virt-manager/virtManager/domain.py", line 1393, in startup
self._backend.create()
File "/usr/lib64/python2.7/site-packages/libvirt.py", line 966, in create
if ret == -1: raise libvirtError ('virDomainCreate() failed', dom=self)
libvirtError: unsupported configuration: hypervisor lacks deviceboot feature
--------------
Which tells me that it's not individual capabilities that are broken by qemu 65207c59, but the entire libvirt capability retrieval. Apparently libvirt is one user of that async monitor interface. (The message on commit 65207c59 itself mentions "qmp_capabilities".)
Sorry about the substandard formatting in the email, I'm in a bit of a hurry.
Bisection log attached.
Thanks
Laszlo
9 years, 5 months
[libvirt] poor virtio-scsi performance
by Vasiliy Tolstov
Hi all!
I suspected poor performance of virtio-scsi driver.
I did a few tests:
Host machine: linux 3.19.1, QEMU emulator version 2.3.0
Guest machine: linux 4.0.4
part of domain xml:
<emulator>/usr/bin/kvm</emulator>
<disk type='block' device='disk'>
<driver name='qemu' type='raw' cache='none' io='native' discard='unmap'/>
<source dev='/dev/ram0'/>
<backingStore/>
<target dev='sda' bus='scsi'/>
<alias name='scsi0-0-0-1'/>
<address type='drive' controller='0' bus='0' target='0' unit='1'/>
</disk>
/dev/ram0 I got by running `modprobe brd rd_size=$((5*1024*1024))` on
host machine.
fio conf:
[readtest]
blocksize=4k
filename=/dev/sdb (/dev/ram0 whe test from host machine)
rw=randread
direct=1
buffered=0
ioengine=libaio
iodepth=32
results:
from host:
bw=1594.6MB/s, iops=408196, clat=76usec
from guest:
bw=398MB/s, iops=99720, clat=316usec
Both host and guest system I boot with `scsi_mod.use_blk_mq=Y`.
Why difference in 4 times?!
--
Vasiliy Tolstov,
e-mail: v.tolstov(a)selfip.ru
9 years, 5 months
[libvirt] [PATCH v2] utiltest: Use int8_t instead of char.
by Michal Privoznik
Not every architecture out there has 'char' signed by default.
For instance, my arm box has it unsigned by default:
$ gcc -dM -E - < /dev/null | grep __CHAR_UNSIGNED__
#define __CHAR_UNSIGNED__ 1
Therefore, after 65c61e50 the test if failing for me. Problem is,
we are trying to assign couple of negative values into char
assuming some will overflow and some don't. That can't be the
case if 'char' is unsigned by default. Lets use more explicit types
instead: int8_t and uint8_t where is no ambiguity.
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
tests/utiltest.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tests/utiltest.c b/tests/utiltest.c
index 3a1f8eb..98c689d 100644
--- a/tests/utiltest.c
+++ b/tests/utiltest.c
@@ -184,8 +184,8 @@ static int
testOverflowCheckMacro(const void *data ATTRIBUTE_UNUSED)
{
long long tmp;
- unsigned char luchar;
- char lchar;
+ uint8_t luchar;
+ int8_t lchar;
TEST_OVERFLOW(luchar, 254, false);
TEST_OVERFLOW(luchar, 255, false);
--
2.3.6
9 years, 5 months