[libvirt] [PATCH] docs: Enhance documentation of the old-style boot configuration
by Jiri Denemark
Also encourages people to use per-device boot elements for better
control.
---
docs/formatdomain.html.in | 22 +++++++++++++++++-----
1 files changed, 17 insertions(+), 5 deletions(-)
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 6bf64a6..ff09113 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -131,12 +131,24 @@
<dd>The <code>dev</code> attribute takes one of the values "fd", "hd",
"cdrom" or "network" and is used to specify the next boot device
to consider. The <code>boot</code> element can be repeated multiple
- times to setup a priority list of boot devices to try in turn. The
- <code>boot</code> element cannot be used if per-device boot elements
- are used (see <a href="#elementsDisks">disks</a>,
+ times to setup a priority list of boot devices to try in turn.
+ Multiple devices of the same type are sorted according to their
+ targets while preserving the order of buses. After defining the
+ domain, its XML configuration returned by libvirt (through
+ virDomainGetXMLDesc) lists devices in the sorted order. Once sorted,
+ the first device is marked as bootable. Thus, e.g., a domain
+ configured to boot from "hd" with vdb, hda, vda, and hdc disks
+ assigned to it will boot from vda (the sorted list is vda, vdb, hda,
+ hdc). Similar domain with hdc, vda, vdb, and hda disks will boot from
+ hda (sorted disks are: hda, hdc, vda, vdb). It can be tricky to
+ configure in the desired way, which is why per-device boot elements
+ (see <a href="#elementsDisks">disks</a>,
<a href="#elementsNICS">network interfaces</a>, and
- <a href="#elementsUSB">USB and PCI devices</a> sections below).
- <span class="since">Since 0.1.3, per-device boot since 0.8.8</span>
+ <a href="#elementsUSB">USB and PCI devices</a> sections below) were
+ introduced and they are the preferred way providing full control over
+ booting order. The <code>boot</code> element and per-device boot
+ elements are mutually exclusive. <span class="since">Since 0.1.3,
+ per-device boot since 0.8.8</span>
</dd>
<dt><code>bootmenu</code></dt>
<dd> Whether or not to enable an interactive boot menu prompt on guest
--
1.7.8.4
12 years, 9 months
[libvirt] [PATCH] tests: Fix build with -Werror
by Jiri Denemark
---
Pushed as build-breaker.
Use of uninitialized "n" after the former "error" label was the issue
(gcc didn't get it right though). I forgot to mention this in the
commit message :-(
tests/cputest.c | 17 +++++++----------
1 files changed, 7 insertions(+), 10 deletions(-)
diff --git a/tests/cputest.c b/tests/cputest.c
index 15614a7..870f99f 100644
--- a/tests/cputest.c
+++ b/tests/cputest.c
@@ -126,17 +126,17 @@ cpuTestLoadMultiXML(const char *arch,
goto cleanup;
if (!(doc = virXMLParseFileCtxt(xml, &ctxt)))
- goto error;
+ goto cleanup;
n = virXPathNodeSet("/cpuTest/cpu", ctxt, &nodes);
if (n <= 0 || (VIR_ALLOC_N(cpus, n) < 0))
- goto error;
+ goto cleanup;
for (i = 0; i < n; i++) {
ctxt->node = nodes[i];
cpus[i] = virCPUDefParseXML(nodes[i], ctxt, VIR_CPU_TYPE_HOST);
if (!cpus[i])
- goto error;
+ goto cleanup_cpus;
}
*count = n;
@@ -148,13 +148,10 @@ cleanup:
xmlFreeDoc(doc);
return cpus;
-error:
- if (cpus) {
- for (i = 0; i < n; i++)
- virCPUDefFree(cpus[i]);
- VIR_FREE(cpus);
- cpus = NULL;
- }
+cleanup_cpus:
+ for (i = 0; i < n; i++)
+ virCPUDefFree(cpus[i]);
+ VIR_FREE(cpus);
goto cleanup;
}
--
1.7.8.4
12 years, 9 months
[libvirt] [PATCH] apparmor: Add missing comma
by Jiri Denemark
Typo introduced by c18a88ac
---
Pushed as build-breaker.
src/security/virt-aa-helper.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/src/security/virt-aa-helper.c b/src/security/virt-aa-helper.c
index 1971f40..3c9e541 100644
--- a/src/security/virt-aa-helper.c
+++ b/src/security/virt-aa-helper.c
@@ -917,7 +917,7 @@ get_files(vahControl * ctl)
int ret = virDomainDiskDefForeachPath(ctl->def->disks[i],
ctl->allowDiskFormatProbing,
true,
- -1, -1 /* current uid:gid */
+ -1, -1, /* current uid:gid */
add_file_path,
&buf);
if (ret != 0)
--
1.7.8.4
12 years, 9 months
[libvirt] [PATCH] virsh: Avoid invalid read of size errors
by ajia@redhat.com
From: Alex Jia <ajia(a)redhat.com>
Detected by valgrind. the codes are allocating 0 bytes memory to variable
cpumap by vshCalloc function, and then the function VIR_USE_CPU will access
it later, a invalid read error will be hit.
* tools/virsh.c(cmdVcpuPin): fix invalid read error.
* How to reproduce?
% valgrind -v --read-var-info=yes virsh vcpupin <domain> 0 0
* Actual result:
==27271== ERROR SUMMARY: 5 errors from 2 contexts (suppressed: 8 from 6)
==27271==
==27271== 1 errors in context 1 of 2:
==27271== Invalid read of size 1
==27271== at 0x39CF087E2E: __GI_memcpy (in /lib64/libc-2.12.so)
==27271== by 0x39CF114FDC: xdrmem_putbytes (in /lib64/libc-2.12.so)
==27271== by 0x39CF114707: xdr_opaque (in /lib64/libc-2.12.so)
==27271== by 0x4D56194: xdr_remote_domain_pin_vcpu_args (remote_protocol.c:1844)
==27271== by 0x4D6CCE1: virNetMessageEncodePayload (virnetmessage.c:341)
==27271== by 0x4D5A44B: virNetClientProgramCall (virnetclientprogram.c:327)
==27271== by 0x4D36EDB: callWithFD (remote_driver.c:4546)
==27271== by 0x4D36F7B: call (remote_driver.c:4567)
==27271== by 0x4D3B2C1: remoteDomainPinVcpu (remote_client_bodies.h:1566)
==27271== by 0x4D199D3: virDomainPinVcpu (libvirt.c:8585)
==27271== by 0x4241F4: cmdVcpuPin (virsh.c:5262)
==27271== by 0x4150A6: vshCommandRun (virsh.c:17712)
==27271== Address 0x5602b80 is 0 bytes after a block of size 0 alloc'd
==27271== at 0x4A04A28: calloc (vg_replace_malloc.c:467)
==27271== by 0x4C89BDF: virAllocN (memory.c:129)
==27271== by 0x423868: _vshCalloc.clone.2 (virsh.c:454)
==27271== by 0x423EF9: cmdVcpuPin (virsh.c:5190)
==27271== by 0x4150A6: vshCommandRun (virsh.c:17712)
==27271== by 0x426583: main (virsh.c:19289)
==27271==
==27271==
==27271== 4 errors in context 2 of 2:
==27271== Invalid read of size 1
==27271== at 0x424133: cmdVcpuPin (virsh.c:5245)
==27271== by 0x4150A6: vshCommandRun (virsh.c:17712)
==27271== by 0x426583: main (virsh.c:19289)
==27271== Address 0x5602b80 is 0 bytes after a block of size 0 alloc'd
==27271== at 0x4A04A28: calloc (vg_replace_malloc.c:467)
==27271== by 0x4C89BDF: virAllocN (memory.c:129)
==27271== by 0x423868: _vshCalloc.clone.2 (virsh.c:454)
==27271== by 0x423EF9: cmdVcpuPin (virsh.c:5190)
==27271== by 0x4150A6: vshCommandRun (virsh.c:17712)
==27271== by 0x426583: main (virsh.c:19289)
Signed-off-by: Alex Jia <ajia(a)redhat.com>
---
tools/virsh.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/tools/virsh.c b/tools/virsh.c
index 72ca93a..1613d2e 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -5187,7 +5187,7 @@ cmdVcpuPin(vshControl *ctl, const vshCmd *cmd)
/* Pin mode: pinning specified vcpu to specified physical cpus*/
- cpumap = vshCalloc(ctl, 0, cpumaplen);
+ cpumap = vshCalloc(ctl, cpumaplen, sizeof(cpumap));
/* Parse cpulist */
cur = cpulist;
if (*cur == 0) {
--
1.7.1
12 years, 9 months
[libvirt] [PATCH 1/4] add a qemu-specific event register API, to passthough the new events come from qemu
by shaohef@linux.vnet.ibm.com
From: ShaoHe Feng <shaohef(a)linux.vnet.ibm.com>
Basically, this feature can go along with qemu monitor passthrough.
That way, if we use new commands in the monitor that generate new events, we want some way to receive those new events too.
Signed-off-by: ShaoHe Feng <shaohef(a)linux.vnet.ibm.com>
---
include/libvirt/libvirt-qemu.h | 27 ++++
include/libvirt/libvirt.h.in | 2 +-
src/conf/domain_event.c | 293 ++++++++++++++++++++++++++++++++++++++--
src/conf/domain_event.h | 50 ++++++-
src/driver.h | 14 ++
src/libvirt-qemu.c | 189 ++++++++++++++++++++++++++
src/libvirt_private.syms | 6 +
src/libvirt_qemu.syms | 5 +
8 files changed, 571 insertions(+), 15 deletions(-)
diff --git a/include/libvirt/libvirt-qemu.h b/include/libvirt/libvirt-qemu.h
index 7f12e4f..3aa944a 100644
--- a/include/libvirt/libvirt-qemu.h
+++ b/include/libvirt/libvirt-qemu.h
@@ -32,6 +32,33 @@ virDomainPtr virDomainQemuAttach(virConnectPtr domain,
unsigned int pid,
unsigned int flags);
+/**
+ * virConnectDomainQemuEventCallback:
+ * @conn: connection object
+ * @dom: domain on which the event occurred
+ * @eventName : the name of the unknow or un-implementation event
+ * @eventArgs: the content of the unknow or un-implementation event
+ *
+ * The callback signature to use when registering for an event of type
+ * VIR_QEMU_DOMAIN_EVENT_ID_UNKNOWN with virConnectDomainQemuEventRegister()
+ */
+typedef void (*virConnectDomainQemuEventCallback)(virConnectPtr conn,
+ virDomainPtr dom,
+ const char *eventName, /* The JSON event name */
+ const char *eventArgs, /* The JSON string of args */
+ void *opaque);
+
+int
+virConnectDomainQemuEventRegister(virConnectPtr conn,
+ virDomainPtr dom, /* option to filter */
+ const char *eventName, /* JSON event name */
+ virConnectDomainQemuEventCallback cb,
+ void *opaque,
+ virFreeCallback freecb);
+int
+virConnectDomainQemuEventDeregister(virConnectPtr conn,
+ int callbackID);
+
# ifdef __cplusplus
}
# endif
diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index 2480add..9fcb400 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -3207,7 +3207,6 @@ typedef void (*virConnectDomainEventBlockJobCallback)(virConnectPtr conn,
int type,
int status,
void *opaque);
-
/**
* virConnectDomainEventDiskChangeReason:
*
@@ -3263,6 +3262,7 @@ typedef enum {
VIR_DOMAIN_EVENT_ID_CONTROL_ERROR = 7, /* virConnectDomainEventGenericCallback */
VIR_DOMAIN_EVENT_ID_BLOCK_JOB = 8, /* virConnectDomainEventBlockJobCallback */
VIR_DOMAIN_EVENT_ID_DISK_CHANGE = 9, /* virConnectDomainEventDiskChangeCallback */
+ VIR_QEMU_DOMAIN_EVENT_ID_UNKNOWN = 10, /* virConnectDomainEventDefaultCallback */
/*
* NB: this enum value will increase over time as new events are
diff --git a/src/conf/domain_event.c b/src/conf/domain_event.c
index 614ab97..0388a66 100644
--- a/src/conf/domain_event.c
+++ b/src/conf/domain_event.c
@@ -45,7 +45,9 @@ typedef virDomainMeta *virDomainMetaPtr;
struct _virDomainEventCallback {
int callbackID;
+ int qemuCallbackID;
int eventID;
+ char *eventName;
virConnectPtr conn;
virDomainMetaPtr dom;
virConnectDomainEventGenericCallback cb;
@@ -94,6 +96,10 @@ struct _virDomainEvent {
char *devAlias;
int reason;
} diskChange;
+ struct {
+ char *eventName;
+ char *eventArgs;
+ }qemuUnknownEvent;
} data;
};
@@ -112,6 +118,7 @@ virDomainEventCallbackListFree(virDomainEventCallbackListPtr list)
for (i=0; i<list->count; i++) {
virFreeCallback freecb = list->callbacks[i]->freecb;
+ VIR_FREE(list->callbacks[i]->eventName);
if (freecb)
(*freecb)(list->callbacks[i]->opaque);
VIR_FREE(list->callbacks[i]);
@@ -187,8 +194,10 @@ virDomainEventCallbackListRemoveID(virConnectPtr conn,
if (freecb)
(*freecb)(cbList->callbacks[i]->opaque);
virUnrefConnect(cbList->callbacks[i]->conn);
+ if (cbList->callbacks[i]->eventID == VIR_QEMU_DOMAIN_EVENT_ID_UNKNOWN) {
+ VIR_FREE(cbList->callbacks[i]->eventName);
+ }
VIR_FREE(cbList->callbacks[i]);
-
if (i < (cbList->count - 1))
memmove(cbList->callbacks + i,
cbList->callbacks + i + 1,
@@ -231,6 +240,9 @@ virDomainEventCallbackListRemoveConn(virConnectPtr conn,
if (freecb)
(*freecb)(cbList->callbacks[i]->opaque);
virUnrefConnect(cbList->callbacks[i]->conn);
+ if (cbList->callbacks[i]->eventID == VIR_QEMU_DOMAIN_EVENT_ID_UNKNOWN) {
+ VIR_FREE(cbList->callbacks[i]->eventName);
+ }
VIR_FREE(cbList->callbacks[i]);
if (i < (cbList->count - 1))
@@ -299,6 +311,9 @@ int virDomainEventCallbackListPurgeMarked(virDomainEventCallbackListPtr cbList)
if (freecb)
(*freecb)(cbList->callbacks[i]->opaque);
virUnrefConnect(cbList->callbacks[i]->conn);
+ if (cbList->callbacks[i]->eventID == VIR_QEMU_DOMAIN_EVENT_ID_UNKNOWN) {
+ VIR_FREE(cbList->callbacks[i]->eventName);
+ }
VIR_FREE(cbList->callbacks[i]);
if (i < (cbList->count - 1))
@@ -404,7 +419,98 @@ virDomainEventCallbackListAddID(virConnectPtr conn,
cbList->callbacks[cbList->count] = event;
cbList->count++;
+ event->callbackID = cbList->nextID++;
+
+ return event->callbackID;
+
+no_memory:
+ virReportOOMError();
+
+ if (event) {
+ if (event->dom)
+ VIR_FREE(event->dom->name);
+ VIR_FREE(event->dom);
+ }
+ VIR_FREE(event);
+ return -1;
+}
+
+
+
+/**
+ * virDomainEventCallbackListAddName:
+ * @conn: pointer to the connection
+ * @cbList: the list
+ * @eventName: the event eventName
+ * @callback: the callback to add
+ * @eventID: the specific eventID
+ * @opaque: opaque data tio pass to callback
+ *
+ * Internal function to add a callback from a virDomainEventCallbackListPtr
+ */
+int
+virDomainEventCallbackListAddName(virConnectPtr conn,
+ virDomainEventCallbackListPtr cbList,
+ virDomainPtr dom,
+ const char* eventName,
+ int eventID,
+ virConnectDomainEventGenericCallback callback,
+ void *opaque,
+ virFreeCallback freecb)
+{
+ virDomainEventCallbackPtr event;
+ int i;
+
+ /* Check incoming */
+ if ( !cbList ) {
+ return -1;
+ }
+
+ /* check if we already have this callback on our list */
+ for (i = 0 ; i < cbList->count ; i++) {
+ if (cbList->callbacks[i]->cb == VIR_DOMAIN_EVENT_CALLBACK(callback) &&
+ STREQ(cbList->callbacks[i]->eventName, eventName) &&
+ cbList->callbacks[i]->eventID == eventID &&
+ cbList->callbacks[i]->conn == conn) {
+ eventReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("event callback already tracked"));
+ return -1;
+ }
+ }
+ if (eventID > VIR_DOMAIN_EVENT_ID_LAST || eventID < VIR_DOMAIN_EVENT_ID_LIFECYCLE) {
+ eventReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("not suport this kind of eventID: %d"), eventID);
+ }
+ /* Allocate new event */
+ if (VIR_ALLOC(event) < 0)
+ goto no_memory;
+ event->conn = conn;
+ event->cb = callback;
+ if (eventName == NULL)
+ goto no_memory;
+ event->eventName = strdup(eventName);
+ if ( event->eventName == NULL)
+ goto no_memory;
+ event->opaque = opaque;
+ event->freecb = freecb;
+ event->eventID = eventID;
+ if (dom) {
+ if (VIR_ALLOC(event->dom) < 0)
+ goto no_memory;
+ if (!(event->dom->name = strdup(dom->name)))
+ goto no_memory;
+ memcpy(event->dom->uuid, dom->uuid, VIR_UUID_BUFLEN);
+ event->dom->id = dom->id;
+ }
+ /* Make space on list */
+ if (VIR_REALLOC_N(cbList->callbacks, cbList->count + 1) < 0)
+ goto no_memory;
+
+ event->conn->refs++;
+
+ cbList->callbacks[cbList->count] = event;
+ cbList->count++;
event->callbackID = cbList->nextID++;
return event->callbackID;
@@ -416,11 +522,40 @@ no_memory:
if (event->dom)
VIR_FREE(event->dom->name);
VIR_FREE(event->dom);
+ VIR_FREE(event->eventName);
}
VIR_FREE(event);
return -1;
}
+/**
+ * virDomainEventCallbackListAddQemuCallbackID:
+ * @conn: pointer to the connection
+ * @cbList: the list
+ * @callbackID: the libvirt callback ID
+ * @qemuCallbackID: the libvirtd callback ID to add
+ *
+ * Internal function to add a Daemon libvirtd callbackID
+ */
+int
+virDomainEventCallbackListAddQemuCallbackID(virConnectPtr conn,
+ virDomainEventCallbackListPtr cbList,
+ int callbackID,
+ int qemuCallbackID)
+{
+ int i;
+ for (i = 0 ; i < cbList->count ; i++) {
+ if (cbList->callbacks[i]->callbackID == callbackID &&
+ cbList->callbacks[i]->conn == conn) {
+ cbList->callbacks[i]->qemuCallbackID = qemuCallbackID;
+ return 0;
+ }
+ }
+
+ eventReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("could not find event callback for deletion"));
+ return -1;
+}
int virDomainEventCallbackListCountID(virConnectPtr conn,
virDomainEventCallbackListPtr cbList,
@@ -442,6 +577,27 @@ int virDomainEventCallbackListCountID(virConnectPtr conn,
}
+int
+virDomainEventCallbackListCountName(virConnectPtr conn,
+ virDomainEventCallbackListPtr cbList,
+ const char *eventName)
+{
+ int i;
+ int count = 0;
+
+ for (i = 0 ; i < cbList->count ; i++) {
+ if (cbList->callbacks[i]->deleted)
+ continue;
+
+ if (STREQ(cbList->callbacks[i]->eventName,eventName) &&
+ cbList->callbacks[i]->conn == conn)
+ count++;
+ }
+
+ return count;
+}
+
+
int virDomainEventCallbackListEventID(virConnectPtr conn,
virDomainEventCallbackListPtr cbList,
int callbackID)
@@ -461,6 +617,44 @@ int virDomainEventCallbackListEventID(virConnectPtr conn,
}
+const char*
+virDomainEventCallbackListEventName(virConnectPtr conn,
+ virDomainEventCallbackListPtr cbList,
+ int callbackID)
+{
+ int i;
+
+ for (i = 0 ; i < cbList->count ; i++) {
+ if (cbList->callbacks[i]->deleted)
+ continue;
+
+ if (cbList->callbacks[i]->callbackID == callbackID &&
+ cbList->callbacks[i]->conn == conn)
+ return cbList->callbacks[i]->eventName;
+ }
+
+ return NULL;
+}
+
+int
+virDomainEventCallbackListEventQemuCallbackID(virConnectPtr conn,
+ virDomainEventCallbackListPtr cbList,
+ int callbackID)
+{
+ int i;
+
+ for (i = 0 ; i < cbList->count ; i++) {
+ if (cbList->callbacks[i]->deleted)
+ continue;
+
+ if (cbList->callbacks[i]->callbackID == callbackID &&
+ cbList->callbacks[i]->conn == conn)
+ return cbList->callbacks[i]->qemuCallbackID;
+ }
+
+ return -1;
+}
+
int virDomainEventCallbackListCount(virDomainEventCallbackListPtr cbList)
{
int i;
@@ -521,6 +715,11 @@ void virDomainEventFree(virDomainEventPtr event)
VIR_FREE(event->data.diskChange.newSrcPath);
VIR_FREE(event->data.diskChange.devAlias);
break;
+
+ case VIR_QEMU_DOMAIN_EVENT_ID_UNKNOWN:
+ VIR_FREE(event->data.qemuUnknownEvent.eventName);
+ VIR_FREE(event->data.qemuUnknownEvent.eventArgs);
+ break;
}
VIR_FREE(event->dom.name);
@@ -956,6 +1155,51 @@ virDomainEventPtr virDomainEventBlockJobNewFromDom(virDomainPtr dom,
path, type, status);
}
+static virDomainEventPtr
+virDomainEventUnknownNew(int id, const char *name, unsigned char *uuid,
+ const char *eventName, const char *eventArgs)
+{
+ virDomainEventPtr ev =
+ virDomainEventNewInternal(VIR_QEMU_DOMAIN_EVENT_ID_UNKNOWN,
+ id, name, uuid);
+ if (ev) {
+ if (!(ev->data.qemuUnknownEvent.eventName = strdup(eventName))) {
+ virReportOOMError();
+ VIR_FREE(ev->dom.name);
+ VIR_FREE(ev);
+ return NULL;
+ }
+ if (eventArgs) {
+ if (!(ev->data.qemuUnknownEvent.eventArgs = strdup(eventArgs))) {
+ virReportOOMError();
+ VIR_FREE(ev->data.qemuUnknownEvent.eventName);
+ VIR_FREE(ev->dom.name);
+ VIR_FREE(ev);
+ return NULL;
+ }
+ }
+ }
+
+ return ev;
+}
+
+virDomainEventPtr virDomainEventUnknownNewFromObj(virDomainObjPtr obj,
+ const char *eventName,
+ const char *eventArgs)
+{
+
+ return virDomainEventUnknownNew(obj->def->id, obj->def->name,
+ obj->def->uuid, eventName, eventArgs);
+}
+
+virDomainEventPtr virDomainEventUnknownNewFromDom(virDomainPtr dom,
+ const char *eventName,
+ const char *eventArgs)
+{
+ return virDomainEventUnknownNew(dom->id, dom->name, dom->uuid,
+ eventName, eventArgs);
+}
+
virDomainEventPtr virDomainEventControlErrorNewFromDom(virDomainPtr dom)
{
virDomainEventPtr ev =
@@ -1095,11 +1339,12 @@ virDomainEventQueuePush(virDomainEventQueuePtr evtQueue,
}
-void virDomainEventDispatchDefaultFunc(virConnectPtr conn,
- virDomainEventPtr event,
- virConnectDomainEventGenericCallback cb,
- void *cbopaque,
- void *opaque ATTRIBUTE_UNUSED)
+void
+virDomainEventDispatchDefaultFunc(virConnectPtr conn,
+ virDomainEventPtr event,
+ virConnectDomainEventGenericCallback cb,
+ void *cbopaque,
+ void *opaque ATTRIBUTE_UNUSED)
{
virDomainPtr dom = virGetDomain(conn, event->dom.name, event->dom.uuid);
if (!dom)
@@ -1180,6 +1425,13 @@ void virDomainEventDispatchDefaultFunc(virConnectPtr conn,
cbopaque);
break;
+ case VIR_QEMU_DOMAIN_EVENT_ID_UNKNOWN:
+ ((virConnectDomainQemuEventCallback)cb)(conn, dom,
+ event->data.qemuUnknownEvent.eventName,
+ event->data.qemuUnknownEvent.eventArgs,
+ cbopaque);
+ break;
+
default:
VIR_WARN("Unexpected event ID %d", event->eventID);
break;
@@ -1189,8 +1441,9 @@ void virDomainEventDispatchDefaultFunc(virConnectPtr conn,
}
-static int virDomainEventDispatchMatchCallback(virDomainEventPtr event,
- virDomainEventCallbackPtr cb)
+static int
+virDomainEventDispatchMatchCallback(virDomainEventPtr event,
+ virDomainEventCallbackPtr cb)
{
if (!cb)
return 0;
@@ -1198,7 +1451,12 @@ static int virDomainEventDispatchMatchCallback(virDomainEventPtr event,
return 0;
if (cb->eventID != event->eventID)
return 0;
-
+ if (event->eventID == VIR_QEMU_DOMAIN_EVENT_ID_UNKNOWN) {
+ if (event->data.qemuUnknownEvent.eventName == NULL ||
+ cb->eventName == NULL ||
+ STRNEQ(cb->eventName, event->data.qemuUnknownEvent.eventName))
+ return 0;
+ }
if (cb->dom) {
/* Deliberately ignoring 'id' for matching, since that
* will cause problems when a domain switches between
@@ -1341,3 +1599,20 @@ virDomainEventStateDeregisterAny(virConnectPtr conn,
virDomainEventStateUnlock(state);
return ret;
}
+int
+virDomainQemuEventStateDeregister(virConnectPtr conn,
+ virDomainEventStatePtr state,
+ int callbackID)
+{
+ int ret;
+
+ virDomainEventStateLock(state);
+ if (state->isDispatching)
+ ret = virDomainEventCallbackListMarkDeleteID(conn,
+ state->callbacks, callbackID);
+ else
+ ret = virDomainEventCallbackListRemoveID(conn,
+ state->callbacks, callbackID);
+ virDomainEventStateUnlock(state);
+ return ret;
+}
diff --git a/src/conf/domain_event.h b/src/conf/domain_event.h
index 3ba418e..f2fe847 100644
--- a/src/conf/domain_event.h
+++ b/src/conf/domain_event.h
@@ -83,14 +83,23 @@ int virDomainEventCallbackListAddID(virConnectPtr conn,
virFreeCallback freecb)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(5);
+int virDomainEventCallbackListAddName(virConnectPtr conn,
+ virDomainEventCallbackListPtr cbList,
+ virDomainPtr dom,
+ const char* eventName,
+ int eventID,
+ virConnectDomainEventGenericCallback callback,
+ void *opaque,
+ virFreeCallback freecb)
+ ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(4) ATTRIBUTE_NONNULL(6);
int virDomainEventCallbackListRemove(virConnectPtr conn,
virDomainEventCallbackListPtr cbList,
virConnectDomainEventCallback callback)
ATTRIBUTE_NONNULL(1);
-int virDomainEventCallbackListRemoveID(virConnectPtr conn,
- virDomainEventCallbackListPtr cbList,
- int callbackID)
+int virDomainQemuEventCallbackListRemoveID(virConnectPtr conn,
+ virDomainEventCallbackListPtr cbList,
+ int callbackID)
ATTRIBUTE_NONNULL(1);
int virDomainEventCallbackListRemoveConn(virConnectPtr conn,
virDomainEventCallbackListPtr cbList)
@@ -106,9 +115,14 @@ int virDomainEventCallbackListMarkDeleteID(virConnectPtr conn,
int callbackID)
ATTRIBUTE_NONNULL(1);
-
int virDomainEventCallbackListPurgeMarked(virDomainEventCallbackListPtr cbList);
+int virDomainEventCallbackListAddQemuCallbackID(virConnectPtr conn,
+ virDomainEventCallbackListPtr cbList,
+ int callbackID,
+ int qemuCallbackID)
+ ATTRIBUTE_NONNULL(1);
+
int virDomainEventCallbackListCount(virDomainEventCallbackListPtr cbList);
int virDomainEventCallbackListCountID(virConnectPtr conn,
virDomainEventCallbackListPtr cbList,
@@ -119,6 +133,21 @@ int virDomainEventCallbackListEventID(virConnectPtr conn,
int callbackID)
ATTRIBUTE_NONNULL(1);
+int virDomainEventCallbackListCountName(virConnectPtr conn,
+ virDomainEventCallbackListPtr cbList,
+ const char *eventName)
+ ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(3);
+
+int virDomainEventCallbackListEventQemuCallbackID(virConnectPtr conn,
+ virDomainEventCallbackListPtr cbList,
+ int callbackID)
+ ATTRIBUTE_NONNULL(1);
+
+const char* virDomainEventCallbackListEventName(virConnectPtr conn,
+ virDomainEventCallbackListPtr cbList,
+ int callbackID)
+ ATTRIBUTE_NONNULL(1);
+
virDomainEventQueuePtr virDomainEventQueueNew(void);
virDomainEventPtr virDomainEventNew(int id, const char *name, const unsigned char *uuid, int type, int detail);
@@ -190,6 +219,13 @@ virDomainEventPtr virDomainEventDiskChangeNewFromDom(virDomainPtr dom,
const char *devAlias,
int reason);
+virDomainEventPtr virDomainEventUnknownNewFromObj(virDomainObjPtr obj,
+ const char *eventName,
+ const char *eventArgs);
+virDomainEventPtr virDomainEventUnknownNewFromDom(virDomainPtr dom,
+ const char *eventName,
+ const char *eventArgs);
+
int virDomainEventQueuePush(virDomainEventQueuePtr evtQueue,
virDomainEventPtr event);
@@ -246,5 +282,9 @@ virDomainEventStateDeregisterAny(virConnectPtr conn,
virDomainEventStatePtr state,
int callbackID)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
-
+int
+virDomainQemuEventStateDeregister(virConnectPtr conn,
+ virDomainEventStatePtr state,
+ int callbackID)
+ ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
#endif
diff --git a/src/driver.h b/src/driver.h
index 941ff51..51164a9 100644
--- a/src/driver.h
+++ b/src/driver.h
@@ -635,6 +635,18 @@ typedef virDomainPtr
unsigned int flags);
typedef int
+ (*virDrvDomainQemuEventRegister)(virConnectPtr conn,
+ virDomainPtr dom, /* option to filter */
+ const char *eventName, /* JSON event name */
+ virConnectDomainEventGenericCallback cb,
+ void *opaque,
+ virFreeCallback freecb);
+
+typedef int
+ (*virDrvDomainQemuEventDeregister)(virConnectPtr conn,
+ int callbackID);
+
+typedef int
(*virDrvDomainOpenConsole)(virDomainPtr dom,
const char *dev_name,
virStreamPtr st,
@@ -915,6 +927,8 @@ struct _virDriver {
virDrvDomainSnapshotDelete domainSnapshotDelete;
virDrvDomainQemuMonitorCommand qemuDomainMonitorCommand;
virDrvDomainQemuAttach qemuDomainAttach;
+ virDrvDomainQemuEventRegister qemuDomainQemuEventRegister;
+ virDrvDomainQemuEventDeregister qemuDomainQemuEventDeregister;
virDrvDomainOpenConsole domainOpenConsole;
virDrvDomainOpenGraphics domainOpenGraphics;
virDrvDomainInjectNMI domainInjectNMI;
diff --git a/src/libvirt-qemu.c b/src/libvirt-qemu.c
index 248cc33..7722b7b 100644
--- a/src/libvirt-qemu.c
+++ b/src/libvirt-qemu.c
@@ -36,6 +36,77 @@
virReportErrorHelper(VIR_FROM_DOM, error, NULL, __FUNCTION__, \
__LINE__, info)
+/* Helper macros to implement VIR_DOMAIN_DEBUG using just C99. This
+ * assumes you pass fewer than 15 arguments to VIR_DOMAIN_DEBUG, but
+ * can easily be expanded if needed.
+ *
+ * Note that gcc provides extensions of "define a(b...) b" or
+ * "define a(b,...) b,##__VA_ARGS__" as a means of eliding a comma
+ * when no var-args are present, but we don't want to require gcc.
+ */
+#define VIR_ARG15(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, ...) _15
+#define VIR_HAS_COMMA(...) VIR_ARG15(__VA_ARGS__, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0)
+
+/* Form the name VIR_DOMAIN_DEBUG_[01], then call that macro,
+ * according to how many arguments are present. Two-phase due to
+ * macro expansion rules. */
+#define VIR_DOMAIN_DEBUG_EXPAND(a, b, ...) \
+ VIR_DOMAIN_DEBUG_PASTE(a, b, __VA_ARGS__)
+#define VIR_DOMAIN_DEBUG_PASTE(a, b, ...) \
+ a##b(__VA_ARGS__)
+
+/* Internal use only, when VIR_DOMAIN_DEBUG has one argument. */
+#define VIR_DOMAIN_DEBUG_0(dom) \
+ VIR_DOMAIN_DEBUG_2(dom, "%s", "")
+
+/* Internal use only, when VIR_DOMAIN_DEBUG has three or more arguments. */
+#define VIR_DOMAIN_DEBUG_1(dom, fmt, ...) \
+ VIR_DOMAIN_DEBUG_2(dom, ", " fmt, __VA_ARGS__)
+
+/* Internal use only, with final format. */
+#define VIR_DOMAIN_DEBUG_2(dom, fmt, ...) \
+ do { \
+ char _uuidstr[VIR_UUID_STRING_BUFLEN]; \
+ const char *_domname = NULL; \
+ \
+ if (!VIR_IS_DOMAIN(dom)) { \
+ memset(_uuidstr, 0, sizeof(_uuidstr)); \
+ } else { \
+ virUUIDFormat((dom)->uuid, _uuidstr); \
+ _domname = (dom)->name; \
+ } \
+ \
+ VIR_DEBUG("dom=%p, (VM: name=%s, uuid=%s)" fmt, \
+ dom, NULLSTR(_domname), _uuidstr, __VA_ARGS__); \
+ } while (0)
+
+/**
+ * VIR_DOMAIN_DEBUG:
+ * @dom: domain
+ * @fmt: optional format for additional information
+ * @...: optional arguments corresponding to @fmt.
+ */
+#define VIR_DOMAIN_DEBUG(...) \
+ VIR_DOMAIN_DEBUG_EXPAND(VIR_DOMAIN_DEBUG_, \
+ VIR_HAS_COMMA(__VA_ARGS__), \
+ __VA_ARGS__)
+
+/**
+ * VIR_UUID_DEBUG:
+ * @conn: connection
+ * @uuid: possibly null UUID array
+ */
+#define VIR_UUID_DEBUG(conn, uuid) \
+ do { \
+ if (uuid) { \
+ char _uuidstr[VIR_UUID_STRING_BUFLEN]; \
+ virUUIDFormat(uuid, _uuidstr); \
+ VIR_DEBUG("conn=%p, uuid=%s", conn, _uuidstr); \
+ } else { \
+ VIR_DEBUG("conn=%p, uuid=(null)", conn); \
+ } \
+ } while (0)
+
/**
* virDomainQemuMonitorCommand:
* @domain: a domain object
@@ -178,3 +249,121 @@ error:
virDispatchError(conn);
return NULL;
}
+
+/**
+ * virConnectDomainQemuEventRegister:
+ * @conn: pointer to the connection
+ * @dom: pointer to the domain
+ * @eventName: the event Name to receive
+ * @cb: callback to the function handling domain events
+ * @opaque: opaque data to pass on to the callback
+ * @freecb: optional function to deallocate opaque when not used anymore
+ *
+ * Adds a callback to receive notifications of arbitrary qemu domain events
+ * occurring on a domain.
+ *
+ * If dom is NULL, then events will be monitored for any domain. If dom
+ * is non-NULL, then only the specific domain will be monitored
+ *
+ * Most types of event have a callback providing a custom set of parameters
+ * for the event. When registering an event, it is thus neccessary to use
+ * the VIR_DOMAIN_EVENT_CALLBACK() macro to cast the supplied function pointer
+ * to match the signature of this method.
+ *
+ * The virDomainPtr object handle passed into the callback upon delivery
+ * of an event is only valid for the duration of execution of the callback.
+ * If the callback wishes to keep the domain object after the callback returns,
+ * it shall take a reference to it, by calling virDomainRef.
+ * The reference can be released once the object is no longer required
+ * by calling virDomainFree.
+ *
+ * The return value from this method is a positive integer identifier
+ * for the callback. To unregister a callback, this callback ID should
+ * be passed to the virConnectDomainQemuEventDeregister method
+ *
+ * Returns a callback identifier on success, -1 on failure
+ */
+int
+virConnectDomainQemuEventRegister(virConnectPtr conn,
+ virDomainPtr dom, /* option to filter */
+ const char *eventName, /* JSON event name */
+ virConnectDomainQemuEventCallback cb,
+ void *opaque,
+ virFreeCallback freecb)
+{
+ VIR_DOMAIN_DEBUG(dom, "conn=%p, eventName=%s, cb=%p, opaque=%p, freecb=%p",
+ conn, eventName, cb, opaque, freecb);
+
+ virResetLastError();
+
+ if (!VIR_IS_CONNECT(conn)) {
+ virLibConnError(conn, VIR_ERR_INVALID_CONN, __FUNCTION__);
+ virDispatchError(NULL);
+ return -1;
+ }
+ if (dom != NULL &&
+ !(VIR_IS_CONNECTED_DOMAIN(dom) && dom->conn == conn)) {
+ virLibConnError(conn, VIR_ERR_INVALID_CONN, __FUNCTION__);
+ virDispatchError(conn);
+ return -1;
+ }
+ if (eventName == NULL || cb == NULL) {
+ virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+ goto error;
+ }
+
+ if ((conn->driver) && (conn->driver->qemuDomainQemuEventRegister)) {
+ int ret;
+ ret = conn->driver->qemuDomainQemuEventRegister(conn, dom, eventName, cb, opaque, freecb);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError(conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+error:
+ virDispatchError(conn);
+ return -1;
+}
+
+/**
+ * virConnectDomainQemuEventDeregister:
+ * @conn: pointer to the connection
+ * @callbackID: the callback identifier
+ *
+ * Removes an event callback. The callbackID parameter should be the
+ * vaule obtained from a previous virConnectDomainQemuEventDeregister method.
+ *
+ * Returns 0 on success, -1 on failure
+ */
+int
+virConnectDomainQemuEventDeregister(virConnectPtr conn,
+ int callbackID)
+{
+
+ VIR_DEBUG("conn=%p, callbackID=%d", conn, callbackID);
+
+ virResetLastError();
+
+ if (!VIR_IS_CONNECT(conn)) {
+ virLibConnError(conn, VIR_ERR_INVALID_CONN, __FUNCTION__);
+ virDispatchError(NULL);
+ return -1;
+ }
+ if (callbackID < 0) {
+ virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+ goto error;
+ }
+ if ((conn->driver) && (conn->driver->qemuDomainQemuEventDeregister)) {
+ int ret;
+ ret = conn->driver->qemuDomainQemuEventDeregister(conn, callbackID);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError(conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+error:
+ virDispatchError(conn);
+ return -1;
+}
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 48ffdf2..75e544a 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -471,11 +471,16 @@ virDomainWatchdogModelTypeToString;
# domain_event.h
virDomainEventBlockJobNewFromObj;
virDomainEventBlockJobNewFromDom;
+virDomainEventUnknownNewFromObj;
+virDomainEventunknownNewFromDom;
virDomainEventCallbackListAdd;
virDomainEventCallbackListAddID;
+virDomainEventCallbackListAddName;
virDomainEventCallbackListCount;
virDomainEventCallbackListCountID;
+virDomainEventCallbackListCountName;
virDomainEventCallbackListEventID;
+virDomainEventCallbackListEventName;
virDomainEventCallbackListFree;
virDomainEventCallbackListMarkDelete;
virDomainEventCallbackListMarkDeleteID;
@@ -512,6 +517,7 @@ virDomainEventRebootNewFromDom;
virDomainEventRebootNewFromObj;
virDomainEventStateDeregister;
virDomainEventStateDeregisterAny;
+virDomainQemuEventStateDeregister;
virDomainEventStateFlush;
virDomainEventStateFree;
virDomainEventStateNew;
diff --git a/src/libvirt_qemu.syms b/src/libvirt_qemu.syms
index 8447730..a17e387 100644
--- a/src/libvirt_qemu.syms
+++ b/src/libvirt_qemu.syms
@@ -19,3 +19,8 @@ LIBVIRT_QEMU_0.9.4 {
global:
virDomainQemuAttach;
} LIBVIRT_QEMU_0.8.3;
+LIBVIRT_QEMU_0.9.9 {
+ global:
+ virConnectDomainQemuEventRegister;
+ virConnectDomainQemuEventDeregister;
+} LIBVIRT_QEMU_0.9.4;
--
1.7.5.4
12 years, 9 months
[libvirt] [PATCH 1/2 v3] Python: Refactoring virTypedParameter conversion for NUMA tuning APIs
by Guannan Ren
*virDomainSetNumaParameters
*virDomainGetNumaParameters
---
python/Makefile.am | 4 +-
python/libvirt-override-api.xml | 13 ++
python/libvirt-override.c | 314 +++++++++++++++++++++++++++++++++++++++
3 files changed, 330 insertions(+), 1 deletions(-)
diff --git a/python/Makefile.am b/python/Makefile.am
index 3068eee..4302fa5 100644
--- a/python/Makefile.am
+++ b/python/Makefile.am
@@ -8,6 +8,8 @@ SUBDIRS= . tests
INCLUDES = \
$(PYTHON_INCLUDES) \
-I$(top_srcdir)/include \
+ -I$(top_srcdir)/src \
+ -I$(top_srcdir)/gnulib/lib \
-I$(top_builddir)/include \
-I$(top_builddir)/$(subdir) \
$(GETTEXT_CPPFLAGS)
@@ -42,7 +44,7 @@ all-local: libvirt.py libvirt_qemu.py
pyexec_LTLIBRARIES = libvirtmod.la libvirtmod_qemu.la
-libvirtmod_la_SOURCES = libvirt-override.c typewrappers.c
+libvirtmod_la_SOURCES = libvirt-override.c typewrappers.c ../src/util/virtypedparam.c
nodist_libvirtmod_la_SOURCES = libvirt.c libvirt.h
# Python <= 2.4 header files contain a redundant decl, hence we
# need extra flags here
diff --git a/python/libvirt-override-api.xml b/python/libvirt-override-api.xml
index 704fee9..748aa17 100644
--- a/python/libvirt-override-api.xml
+++ b/python/libvirt-override-api.xml
@@ -248,6 +248,19 @@
<arg name='domain' type='virDomainPtr' info='pointer to domain object'/>
<arg name='flags' type='int' info='an OR'ed set of virDomainModificationImpact'/>
</function>
+ <function name='virDomainSetNumaParameters' file='python'>
+ <info>Change the NUMA tunables</info>
+ <return type='int' info='-1 in case of error, 0 in case of success.'/>
+ <arg name='domain' type='virDomainPtr' info='pointer to domain object'/>
+ <arg name='params' type='virTypedParameterPtr' info='pointer to numa tunable objects'/>
+ <arg name='flags' type='int' info='an OR'ed set of virDomainModificationImpact'/>
+ </function>
+ <function name='virDomainGetNumaParameters' file='python'>
+ <info>Get the NUMA parameters</info>
+ <return type='int' info='returns a dictionary of params in case of success, -1 in case of error'/>
+ <arg name='domain' type='virDomainPtr' info='pointer to domain object'/>
+ <arg name='flags' type='int' info='an OR'ed set of virDomainModificationImpact'/>
+ </function>
<function name='virConnectListStoragePools' file='python'>
<info>list the storage pools, stores the pointers to the names in @names</info>
<arg name='conn' type='virConnectPtr' info='pointer to the hypervisor connection'/>
diff --git a/python/libvirt-override.c b/python/libvirt-override.c
index d2aad0f..5f9d83e 100644
--- a/python/libvirt-override.c
+++ b/python/libvirt-override.c
@@ -21,6 +21,7 @@
#include "libvirt/virterror.h"
#include "typewrappers.h"
#include "libvirt.h"
+#include "util/virtypedparam.h"
#ifndef __CYGWIN__
extern void initlibvirtmod(void);
@@ -61,6 +62,208 @@ static char *py_str(PyObject *obj)
return PyString_AsString(str);
}
+/* Two helper functions to help the conversions between C to Python
+ * for the virTypedParameter used in the following APIs. */
+static PyObject *
+getPyVirTypedParameter(virTypedParameterPtr params, int nparams)
+{
+ PyObject *info;
+ PyObject *key, *val;
+ PyObject *ret = NULL;
+ int i;
+
+ if (!params)
+ return ret;
+
+ /* convert to a Python tuple of long objects */
+ if ((info = PyDict_New()) == NULL) {
+ return ret;
+ }
+
+ for (i = 0 ; i < nparams ; i++) {
+ switch (params[i].type) {
+ case VIR_TYPED_PARAM_INT:
+ val = PyInt_FromLong((long)params[i].value.i);
+ break;
+
+ case VIR_TYPED_PARAM_UINT:
+ val = PyInt_FromLong((unsigned long)params[i].value.ui);
+ break;
+
+ case VIR_TYPED_PARAM_LLONG:
+ val = PyLong_FromLongLong((long long)params[i].value.l);
+ break;
+
+ case VIR_TYPED_PARAM_ULLONG:
+ val = PyLong_FromUnsignedLongLong((unsigned long long)params[i].value.ul);
+ break;
+
+ case VIR_TYPED_PARAM_DOUBLE:
+ val = PyFloat_FromDouble((double)params[i].value.d);
+ break;
+
+ case VIR_TYPED_PARAM_BOOLEAN:
+ val = PyBool_FromLong((long)params[i].value.b);
+ break;
+
+ case VIR_TYPED_PARAM_STRING:
+ val = libvirt_constcharPtrWrap(params[i].value.s);
+ break;
+
+ default:
+ Py_DECREF(info);
+ return ret;
+ }
+
+ key = libvirt_constcharPtrWrap(params[i].field);
+ if (!key || !val)
+ goto fail;
+
+ if (PyDict_SetItem(info, key, val) < 0)
+ goto fail;
+
+ Py_DECREF(key);
+ Py_DECREF(val);
+ }
+ return info;
+fail:
+ Py_XDECREF(info);
+ Py_XDECREF(key);
+ Py_XDECREF(val);
+ return ret;
+}
+
+static PyObject *
+setPyVirTypedParameter(PyObject *info, virTypedParameterPtr params, int nparams)
+{
+ PyObject *key, *val;
+ PyObject *ret = NULL;
+ int i;
+
+ if (!info || !params)
+ return ret;
+
+ /* convert to a Python tuple of long objects */
+ for (i = 0; i < nparams; i++) {
+ key = libvirt_constcharPtrWrap(params[i].field);
+ val = PyDict_GetItem(info, key);
+ Py_DECREF(key);
+
+ if (val == NULL)
+ continue;
+
+ switch (params[i].type) {
+ case VIR_TYPED_PARAM_INT:
+ {
+ long long_val;
+ if (PyInt_Check(val)) {
+ long_val = PyInt_AsLong(val);
+ if ((long_val == -1) && PyErr_Occurred())
+ return ret;
+ } else {
+ PyErr_SetString(PyExc_TypeError,
+ "Attribute value type must be int");
+ return ret;
+ }
+ params[i].value.i = (int)long_val;
+ }
+ break;
+ case VIR_TYPED_PARAM_UINT:
+ {
+ long long_val;
+ if (PyInt_Check(val)) {
+ long_val = PyInt_AsLong(val);
+ if ((long_val == -1) && PyErr_Occurred())
+ return ret;
+ } else {
+ PyErr_SetString(PyExc_TypeError,
+ "Attribute value type must be int");
+ return ret;
+ }
+ params[i].value.ui = (unsigned int)long_val;
+ }
+ break;
+ case VIR_TYPED_PARAM_LLONG:
+ {
+ long long llong_val;
+ if (PyLong_Check(val)) {
+ llong_val = PyLong_AsLongLong(val);
+ if ((llong_val == -1) && PyErr_Occurred())
+ return ret;
+ } else {
+ PyErr_SetString(PyExc_TypeError,
+ "Attribute value type must be long");
+ return ret;
+ }
+ params[i].value.l = llong_val;
+ }
+ break;
+ case VIR_TYPED_PARAM_ULLONG:
+ {
+ unsigned long long ullong_val;
+ if (PyLong_Check(val)) {
+ ullong_val = PyLong_AsUnsignedLongLong(val);
+ if ((ullong_val == -1) && PyErr_Occurred())
+ return ret;
+ } else {
+ PyErr_SetString(PyExc_TypeError,
+ "Attribute value type must be long");
+ return ret;
+
+ }
+ params[i].value.ul = ullong_val;
+ }
+ break;
+ case VIR_TYPED_PARAM_DOUBLE:
+ {
+ double double_val;
+ if (PyFloat_Check(val)) {
+ double_val = PyFloat_AsDouble(val);
+ if ((double_val == -1) && PyErr_Occurred())
+ return ret;
+ } else {
+ PyErr_SetString(PyExc_TypeError,
+ "Attribute value type must be float");
+ return ret;
+ }
+ params[i].value.d = double_val;
+ }
+ break;
+ case VIR_TYPED_PARAM_BOOLEAN:
+ {
+ /* Hack - Python's definition of Py_True breaks strict
+ * aliasing rules, so can't directly compare
+ */
+ if (PyBool_Check(val)) {
+ PyObject *hacktrue = PyBool_FromLong(1);
+ params[i].value.b = hacktrue == val ? 1: 0;
+ Py_DECREF(hacktrue);
+ } else {
+ PyErr_SetString(PyExc_TypeError,
+ "Attribute value type must be bool");
+ return ret;
+ }
+ }
+ break;
+ case VIR_TYPED_PARAM_STRING:
+ {
+ if (PyString_Check(val)) {
+ free(params[i].value.s);
+ params[i].value.s = PyString_AsString(val);
+ } else {
+ PyErr_SetString(PyExc_TypeError,
+ "Attribute value type must be string");
+ return ret;
+ }
+ }
+ break;
+ default:
+ return ret;
+ }
+ }
+ return VIR_PY_NONE;
+}
+
/************************************************************************
* *
* Statistics *
@@ -1000,6 +1203,115 @@ libvirt_virDomainGetMemoryParameters(PyObject *self ATTRIBUTE_UNUSED,
}
static PyObject *
+libvirt_virDomainSetNumaParameters(PyObject *self ATTRIBUTE_UNUSED,
+ PyObject *args)
+{
+ virDomainPtr domain;
+ PyObject *pyobj_domain, *info;
+ PyObject *ret = NULL;
+ int i_retval;
+ int nparams = 0;
+ unsigned int flags;
+ virTypedParameterPtr params;
+
+ if (!PyArg_ParseTuple(args,
+ (char *)"OOi:virDomainSetNumaParameters",
+ &pyobj_domain, &info, &flags))
+ return(NULL);
+ domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain);
+
+ LIBVIRT_BEGIN_ALLOW_THREADS;
+ i_retval = virDomainGetNumaParameters(domain, NULL, &nparams, flags);
+ LIBVIRT_END_ALLOW_THREADS;
+
+ if (i_retval < 0)
+ return VIR_PY_INT_FAIL;
+
+ if ((params = malloc(sizeof(*params)*nparams)) == NULL)
+ return PyErr_NoMemory();
+
+ LIBVIRT_BEGIN_ALLOW_THREADS;
+ i_retval = virDomainGetNumaParameters(domain, params, &nparams, flags);
+ LIBVIRT_END_ALLOW_THREADS;
+
+ if (i_retval < 0) {
+ ret = VIR_PY_INT_FAIL;
+ goto fail;
+ }
+
+ if (!setPyVirTypedParameter(info, params, nparams))
+ goto fail;
+
+ LIBVIRT_BEGIN_ALLOW_THREADS;
+ i_retval = virDomainSetNumaParameters(domain, params, nparams, flags);
+ LIBVIRT_END_ALLOW_THREADS;
+
+ if (i_retval < 0) {
+ ret = VIR_PY_INT_FAIL;
+ goto fail;
+ }
+
+ /* The string generated by PyString_AsString
+ * must not be deallocated */
+ free(params);
+ return VIR_PY_INT_SUCCESS;
+fail:
+ /*same as above*/
+ free(params);
+ return ret;
+}
+
+static PyObject *
+libvirt_virDomainGetNumaParameters(PyObject *self ATTRIBUTE_UNUSED,
+ PyObject *args)
+{
+ virDomainPtr domain;
+ PyObject *pyobj_domain, *info;
+ PyObject *ret = NULL;
+ int i_retval;
+ int nparams = 0;
+ unsigned int flags;
+ virTypedParameterPtr params;
+
+ if (!PyArg_ParseTuple(args, (char *)"Oi:virDomainGetNumaParameters",
+ &pyobj_domain, &flags))
+ return(NULL);
+ domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain);
+
+ LIBVIRT_BEGIN_ALLOW_THREADS;
+ i_retval = virDomainGetNumaParameters(domain, NULL, &nparams, flags);
+ LIBVIRT_END_ALLOW_THREADS;
+
+ if (i_retval < 0)
+ return VIR_PY_INT_FAIL;
+
+ if ((params = malloc(sizeof(*params)*nparams)) == NULL)
+ return PyErr_NoMemory();
+
+ LIBVIRT_BEGIN_ALLOW_THREADS;
+ i_retval = virDomainGetNumaParameters(domain, params, &nparams, flags);
+ LIBVIRT_END_ALLOW_THREADS;
+
+ if (i_retval < 0) {
+ ret = VIR_PY_INT_FAIL;
+ goto fail;
+ }
+
+ info = getPyVirTypedParameter(params, nparams);
+ if (!info)
+ goto fail;
+
+ virTypedParameterArrayClear(params, nparams);
+ free(params);
+ return info;
+
+fail:
+ virTypedParameterArrayClear(params, nparams);
+ free(params);
+ return ret;
+}
+
+static PyObject *
libvirt_virDomainGetVcpus(PyObject *self ATTRIBUTE_UNUSED,
PyObject *args) {
virDomainPtr domain;
@@ -5162,6 +5474,8 @@ static PyMethodDef libvirtMethods[] = {
{(char *) "virDomainGetBlkioParameters", libvirt_virDomainGetBlkioParameters, METH_VARARGS, NULL},
{(char *) "virDomainSetMemoryParameters", libvirt_virDomainSetMemoryParameters, METH_VARARGS, NULL},
{(char *) "virDomainGetMemoryParameters", libvirt_virDomainGetMemoryParameters, METH_VARARGS, NULL},
+ {(char *) "virDomainSetNumaParameters", libvirt_virDomainSetNumaParameters, METH_VARARGS, NULL},
+ {(char *) "virDomainGetNumaParameters", libvirt_virDomainGetNumaParameters, METH_VARARGS, NULL},
{(char *) "virDomainGetVcpus", libvirt_virDomainGetVcpus, METH_VARARGS, NULL},
{(char *) "virDomainPinVcpu", libvirt_virDomainPinVcpu, METH_VARARGS, NULL},
{(char *) "virDomainPinVcpuFlags", libvirt_virDomainPinVcpuFlags, METH_VARARGS, NULL},
--
1.7.7.5
12 years, 9 months
[libvirt] [PATCH] maint: consolidate several .gitignore files
by Eric Blake
Unlike .cvsignore under CVS, git allows for ignoring nested
names. We weren't very consistent where new tests were
being ignored (some in .gitignore, some in tests/.gitignore),
and I found it easier to just consolidate everything.
* .gitignore: Subsume entries from subdirectories.
* daemon/.gitignore: Delete.
* docs/.gitignore: Likewise.
* docs/devhelp/.gitignore: Likewise.
* docs/html/.gitignore: Likewise.
* examples/dominfo/.gitignore: Likewise.
* examples/domsuspend/.gitignore: Likewise.
* examples/hellolibvirt/.gitignore: Likewise.
* examples/openauth/.gitignore: Likewise.
* examples/domain-events/events-c/.gitignore: Likewise.
* include/libvirt/.gitignore: Likewise.
* src/.gitignore: Likewise.
* src/esx/.gitignore: Likewise.
* tests/.gitignore: Likewise.
* tools/.gitignore: Likewise.
---
.gitignore | 75 +++++++++++++++++++++++++++-
daemon/.gitignore | 15 ------
docs/.gitignore | 8 ---
docs/devhelp/.gitignore | 4 --
docs/html/.gitignore | 1 -
examples/domain-events/events-c/.gitignore | 6 --
examples/dominfo/.gitignore | 5 --
examples/domsuspend/.gitignore | 5 --
examples/hellolibvirt/.gitignore | 5 --
examples/openauth/.gitignore | 5 --
include/libvirt/.gitignore | 3 -
python/.gitignore | 13 -----
src/.gitignore | 22 --------
src/esx/.gitignore | 1 -
tests/.gitignore | 44 ----------------
tools/.gitignore | 14 -----
16 files changed, 73 insertions(+), 153 deletions(-)
delete mode 100644 daemon/.gitignore
delete mode 100644 docs/.gitignore
delete mode 100644 docs/devhelp/.gitignore
delete mode 100644 docs/html/.gitignore
delete mode 100644 examples/domain-events/events-c/.gitignore
delete mode 100644 examples/dominfo/.gitignore
delete mode 100644 examples/domsuspend/.gitignore
delete mode 100644 examples/hellolibvirt/.gitignore
delete mode 100644 examples/openauth/.gitignore
delete mode 100644 include/libvirt/.gitignore
delete mode 100644 python/.gitignore
delete mode 100644 src/.gitignore
delete mode 100644 src/esx/.gitignore
delete mode 100644 tests/.gitignore
delete mode 100644 tools/.gitignore
diff --git a/.gitignore b/.gitignore
index d1a4226..3e85e4d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,19 +1,28 @@
*#*#
*.#*#
*.a
+*.cov
*.exe
*.gcda
*.gcno
*.gcov
+*.html
+*.i
*.la
*.lo
+*.loT
*.o
*.orig
+*.pyc
*.rej
+*.s
*~
+.deps
.git
.git-module-status
+.libs
.lvimrc
+.memdump
.sc-start-sc_*
/ABOUT-NLS
/COPYING
@@ -37,11 +46,30 @@
/configure
/configure.lineno
/daemon/*_dispatch.h
+/daemon/libvirt_qemud
+/daemon/libvirtd
+/daemon/libvirtd.init
+/daemon/libvirtd.service
+/daemon/libvirtd*.logrotate
+/daemon/libvirtd.8
+/daemon/libvirtd.8.in
+/daemon/libvirtd.pod
+/daemon/probes.h
+/docs/devhelp/libvirt.devhelp
/docs/hvsupport.html.in
+/docs/libvirt-api.xml
/docs/libvirt-qemu-*.xml
+/docs/libvirt-refs.xml
+/docs/todo.html.in
+/examples/domain-events/events-c/event-test
+/examples/dominfo/info1
+/examples/domsuspend/suspend
+/examples/hellolibvirt/hellolibvirt
+/examples/openauth/openauth
/gnulib/lib/*
/gnulib/m4/*
/gnulib/tests/*
+/include/libvirt/libvirt.h
/libtool
/libvirt-*.tar.gz
/libvirt-[0-9]*
@@ -55,31 +83,74 @@
/mkinstalldirs
/po/*
/proxy/
+/python/generated.stamp
/python/generator.py.stamp
+/python/libvirt-export.c
/python/libvirt-qemu-export.c
/python/libvirt-qemu.[ch]
+/python/libvirt.[ch]
+/python/libvirt.py
/python/libvirt_qemu.py
/sc_*
+/src/esx/*.generated.*
/src/hyperv/*.generated.*
-/src/libvirt_iohelper
+/src/libvirt*.def
+/src/libvirt.syms
+/src/libvirt_*.stp
+/src/libvirt_*helper
+/src/libvirt_lxc
/src/locking/qemu-sanlock.conf
+/src/probes.h
/src/remote/*_client_bodies.h
/src/remote/*_protocol.[ch]
/src/rpc/virkeepaliveprotocol.[ch]
/src/rpc/virnetprotocol.[ch]
/src/util/virkeymaps.h
+/src/virt-aa-helper
/tests/*.log
+/tests/*.pid
+/tests/*xml2*test
+/tests/commandhelper
+/tests/conftest
/tests/cputest
/tests/domainsnapshotxml2xmltest
+/tests/esxutilstest
+/tests/eventtest
/tests/hashtest
/tests/jsontest
/tests/networkxml2argvtest
+/tests/nodeinfotest
/tests/nwfilterxml2xmltest
+/tests/object-locking
+/tests/object-locking-files.txt
+/tests/object-locking.cm[ix]
/tests/openvzutilstest
+/tests/qemuargv2xmltest
+/tests/qemuhelptest
/tests/qemuxmlnstest
+/tests/qparamtest
+/tests/reconnect
+/tests/secaatest
+/tests/seclabeltest
+/tests/sexpr2xmltest
/tests/shunloadtest
+/tests/sockettest
+/tests/ssh
+/tests/statstest
+/tests/utiltest
+/tests/virbuftest
/tests/virhashtest
-/tools/virt-host-validate
+/tests/virnet*test
+/tests/virshtest
+/tests/vmx2xmltest
+/tests/xencapstest
+/tests/xmconfigtest
+/tools/*.[18]
+/tools/libvirt-guests.init
+/tools/virsh
+/tools/virsh-*-edit.c
+/tools/virt-*-validate
+/tools/virt-sanlock-cleanup
/update.log
Makefile
Makefile.in
diff --git a/daemon/.gitignore b/daemon/.gitignore
deleted file mode 100644
index 2873143..0000000
--- a/daemon/.gitignore
+++ /dev/null
@@ -1,15 +0,0 @@
-*.la
-*.lo
-.deps
-.libs
-Makefile
-Makefile.in
-libvirt_qemud
-libvirtd
-libvirtd.init
-libvirtd.service
-libvirtd*.logrotate
-libvirtd.8
-libvirtd.8.in
-libvirtd.pod
-probes.h
diff --git a/docs/.gitignore b/docs/.gitignore
deleted file mode 100644
index dd78dd0..0000000
--- a/docs/.gitignore
+++ /dev/null
@@ -1,8 +0,0 @@
-Makefile
-Makefile.in
-.memdump
-apibuild.pyc
-*.html
-libvirt-api.xml
-libvirt-refs.xml
-todo.html.in
diff --git a/docs/devhelp/.gitignore b/docs/devhelp/.gitignore
deleted file mode 100644
index 9c75b93..0000000
--- a/docs/devhelp/.gitignore
+++ /dev/null
@@ -1,4 +0,0 @@
-Makefile
-Makefile.in
-libvirt.devhelp
-*.html
diff --git a/docs/html/.gitignore b/docs/html/.gitignore
deleted file mode 100644
index 2d19fc7..0000000
--- a/docs/html/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-*.html
diff --git a/examples/domain-events/events-c/.gitignore b/examples/domain-events/events-c/.gitignore
deleted file mode 100644
index ed9ac4d..0000000
--- a/examples/domain-events/events-c/.gitignore
+++ /dev/null
@@ -1,6 +0,0 @@
-Makefile
-Makefile.in
-*.exe
-.deps
-.libs
-event-test
diff --git a/examples/dominfo/.gitignore b/examples/dominfo/.gitignore
deleted file mode 100644
index 4626c13..0000000
--- a/examples/dominfo/.gitignore
+++ /dev/null
@@ -1,5 +0,0 @@
-Makefile.in
-Makefile
-.deps
-.libs
-info1
diff --git a/examples/domsuspend/.gitignore b/examples/domsuspend/.gitignore
deleted file mode 100644
index 02eeb79..0000000
--- a/examples/domsuspend/.gitignore
+++ /dev/null
@@ -1,5 +0,0 @@
-Makefile.in
-Makefile
-.deps
-.libs
-suspend
diff --git a/examples/hellolibvirt/.gitignore b/examples/hellolibvirt/.gitignore
deleted file mode 100644
index b8d036d..0000000
--- a/examples/hellolibvirt/.gitignore
+++ /dev/null
@@ -1,5 +0,0 @@
-Makefile
-Makefile.in
-hellolibvirt
-.deps
-.libs
diff --git a/examples/openauth/.gitignore b/examples/openauth/.gitignore
deleted file mode 100644
index 1431557..0000000
--- a/examples/openauth/.gitignore
+++ /dev/null
@@ -1,5 +0,0 @@
-Makefile
-Makefile.in
-openauth
-.deps
-.libs
diff --git a/include/libvirt/.gitignore b/include/libvirt/.gitignore
deleted file mode 100644
index 7bd42da..0000000
--- a/include/libvirt/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-Makefile
-Makefile.in
-libvirt.h
diff --git a/python/.gitignore b/python/.gitignore
deleted file mode 100644
index c191f74..0000000
--- a/python/.gitignore
+++ /dev/null
@@ -1,13 +0,0 @@
-Makefile
-Makefile.in
-.deps
-.libs
-*.lo
-*.la
-*.loT
-libvirt.py
-libvirt-export.c
-libvirt.c
-libvirt.h
-*.pyc
-generated.stamp
diff --git a/src/.gitignore b/src/.gitignore
deleted file mode 100644
index 64e6aec..0000000
--- a/src/.gitignore
+++ /dev/null
@@ -1,22 +0,0 @@
-Makefile
-Makefile.in
-.deps
-.libs
-*.lo
-*.loT
-*.la
-*.exe
-*.cov
-libvirt_parthelper
-libvirt_lxc
-libvirt.def
-libvirt.syms
-libvirt_qemu.def
-*.i
-*.s
-remote_protocol-structs-t
-virt-aa-helper
-libvirt_functions.stp
-libvirt_probes.stp
-probes.o
-probes.h
diff --git a/src/esx/.gitignore b/src/esx/.gitignore
deleted file mode 100644
index 29e1d48..0000000
--- a/src/esx/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-*.generated.*
diff --git a/tests/.gitignore b/tests/.gitignore
deleted file mode 100644
index 027b421..0000000
--- a/tests/.gitignore
+++ /dev/null
@@ -1,44 +0,0 @@
-*.exe
-.deps
-.libs
-ssh
-commandhelper
-commandhelper.log
-commandhelper.pid
-commandtest
-conftest
-esxutilstest
-eventtest
-interfacexml2xmltest
-networkxml2xmltest
-nodedevxml2xmltest
-nodeinfotest
-object-locking
-object-locking-files.txt
-object-locking.cmi
-object-locking.cmx
-qemuargv2xmltest
-qemuhelptest
-qemuxml2argvtest
-qemuxml2xmltest
-qparamtest
-reconnect
-secaatest
-seclabeltest
-sexpr2xmltest
-sockettest
-statstest
-storagepoolxml2xmltest
-storagevolxml2xmltest
-utiltest
-virbuftest
-virnetmessagetest
-virnetsockettest
-virnettlscontexttest
-virshtest
-virtimetest
-vmx2xmltest
-xencapstest
-xmconfigtest
-xml2sexprtest
-xml2vmxtest
diff --git a/tools/.gitignore b/tools/.gitignore
deleted file mode 100644
index 0f7a25e..0000000
--- a/tools/.gitignore
+++ /dev/null
@@ -1,14 +0,0 @@
-libvirt-guests.init
-virt-xml-validate
-virt-pki-validate
-virt-sanlock-cleanup
-*.1
-*.8
-Makefile
-Makefile.in
-virsh-net-edit.c
-virsh-pool-edit.c
-virsh
-*.exe
-.libs
-.deps
--
1.7.7.6
12 years, 9 months
[libvirt] [PATCHv2 0/2] qemu: new GRACEFUL flag for virDomainDestroy
by Laine Stump
This is the 2nd attempt at solving the problem of virDomainDestroy
uncermoniously sending SIGKILL to the qemu process before it's had a
chance to flush its disk buffers. In v1, I altered the default
behavior of virDomainDestroy(), but that was rejected as changing
established API behavior. In v2, the default behavior is maintained,
and a new flag VIR_DOMAIN_DESTROY_GRACEFUL is added fo the
virDomainDestroyFlags API. If that flag is included in the call,
virDomainDestroyFlags will only send SIGTERM to the qemu process, and
if that is unsuccessful, it will return an error rather than sending
SIGKILL.
I've also included a 2nd patch which lengthens the timeout prior to
sending SIGKILL. Although there has been some sentiment against doing
this, my opinion is that it's the prudent thing to do because:
1) The original timeout of 1.6 seconds was arbitrarily selected, and
obviously isn't always adequate.
2) In the cases where the current timeout *is* adequate, there will be
exactly 0 change in behavior anyway. The only time behavior will
change (and that will just be in the form of a longer delay before the
API call returns) will be in those cases where we would otherwise have
caused guest disk corruption. I know which of those two options I
would choose if it was my guest.
3) Just adding a new flag to the libvirt API does not do anything to
help those who are stuck (if only temporarily) with an existing
version of an application that doesn't support the new API flag. Since
libvirt is the cause of the problem, we should try to mitigate the
problem as much as possible without requiring updates of other
packages.
12 years, 9 months
[libvirt] [PATCHv4 0/2] qemu: eliminate "Ignoring open failure" (virFileOpenAs)
by Laine Stump
I believe this version addresses all the issues Eric raised in his
review of V3, *except* those that we agreed should be left for a later patch.
Patch 2/2 is unchanged all the way since v1.
Patch 1/2 has the following changes from V3:
* The "last ditch attempt to open the file in the parent process after
failing with fork+setuid is done only if VIR_FILE_OPEN_NOFORK is
false (meaning that it wasn't already tried). fchmod/fchown is then
performed if necessary.
* fchmod is only attempted after checking the file's current
permissions and seeing that they don't match what is desired.
* fchown and fchmod stuff is moved into a helper function that's
called from 3 places.
* fixed typos, added command about uid & gid no longer being "-1"
Items *NOT* addressed:
* eliminate log messages in child process
* figure out how to have qemuOpenFile call virFileOpenAs just once
* switch from use of waitpid to virPidWait() (and use of
virPidAbort() to cause the child to terminate when an error is
encountered while waiting for an fd from the child.
* figure out when it is appropriate to unlink the file on failure.
* move virFileOpenAs (and several other functions) to virfile.c
12 years, 9 months