On Wed, Feb 23, 2011 at 05:03:02PM -0700, Eric Blake wrote:
* src/qemu/qemu_audit.h (qemuDomainMemoryAudit)
(qemuDomainVcpuAudit): New prototypes.
* src/qemu/qemu_audit.c (qemuDomainResourceAudit)
(qemuDomainMemoryAudit, qemuDomainVcpuAudit): New functions.
(qemuDomainStartAudit): Call as appropriate.
* src/qemu/qemu_driver.c (qemudDomainSetMemory)
(qemudDomainHotplugVcpus): Likewise.
---
v2: fix logic bug (qemuMonitorSet{Balloon,Cpu} returns -1 on monitor
failure, 0 on unsupported, and 1 on success)
src/qemu/qemu_audit.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++
src/qemu/qemu_audit.h | 10 ++++++++
src/qemu/qemu_driver.c | 7 +++++-
3 files changed, 72 insertions(+), 1 deletions(-)
diff --git a/src/qemu/qemu_audit.c b/src/qemu/qemu_audit.c
index c76d49e..6ea31c9 100644
--- a/src/qemu/qemu_audit.c
+++ b/src/qemu/qemu_audit.c
@@ -148,6 +148,59 @@ cleanup:
}
+/**
+ * qemuDomainResourceAudit:
+ * @vm: domain making an integer resource change
+ * @resource: name of the resource: "mem" or "vcpu"
+ * @oldval: the old value of the resource
+ * @newval: the new value of the resource
+ * @reason: either "start" or "update"
+ * @success: true if the resource change succeeded
+ *
+ * Log an audit message about an attempted resource change.
+ */
+static void
+qemuDomainResourceAudit(virDomainObjPtr vm,
+ const char *resource,
+ unsigned long long oldval,
+ unsigned long long newval,
+ const char *reason,
+ bool success)
+{
+ char uuidstr[VIR_UUID_STRING_BUFLEN];
+ char *vmname;
+
+ virUUIDFormat(vm->def->uuid, uuidstr);
+ if (!(vmname = virAuditEncode("vm", vm->def->name))) {
+ VIR_WARN0("OOM while encoding audit message");
+ return;
+ }
+
+ VIR_AUDIT(VIR_AUDIT_RECORD_RESOURCE, success,
+ "resrc=%s reason=%s %s uuid=%s old-%s=%lld new-%s=%lld",
+ resource, reason, vmname, uuidstr,
+ resource, oldval, resource, newval);
+
+ VIR_FREE(vmname);
+}
+
+void
+qemuDomainMemoryAudit(virDomainObjPtr vm,
+ unsigned long long oldmem, unsigned long long newmem,
+ const char *reason, bool success)
+{
+ return qemuDomainResourceAudit(vm, "mem", oldmem, newmem, reason,
success);
+}
+
+void
+qemuDomainVcpuAudit(virDomainObjPtr vm,
+ unsigned int oldvcpu, unsigned int newvcpu,
+ const char *reason, bool success)
+{
+ return qemuDomainResourceAudit(vm, "vcpu", oldvcpu, newvcpu, reason,
+ success);
+}
+
static void qemuDomainLifecycleAudit(virDomainObjPtr vm,
const char *op,
const char *reason,
@@ -185,6 +238,9 @@ void qemuDomainStartAudit(virDomainObjPtr vm, const char *reason,
bool success)
qemuDomainNetAudit(vm, NULL, net, "start", true);
}
+ qemuDomainMemoryAudit(vm, 0, vm->def->mem.cur_balloon, "start",
true);
+ qemuDomainVcpuAudit(vm, 0, vm->def->vcpus, "start", true);
+
qemuDomainLifecycleAudit(vm, "start", reason, success);
}
diff --git a/src/qemu/qemu_audit.h b/src/qemu/qemu_audit.h
index 40f4591..cdbb957 100644
--- a/src/qemu/qemu_audit.h
+++ b/src/qemu/qemu_audit.h
@@ -45,6 +45,16 @@ void qemuDomainCgroupAudit(virDomainObjPtr vm,
const char *item,
const char *name,
bool success);
+void qemuDomainMemoryAudit(virDomainObjPtr vm,
+ unsigned long long oldmem,
+ unsigned long long newmem,
+ const char *reason,
+ bool success);
+void qemuDomainVcpuAudit(virDomainObjPtr vm,
+ unsigned int oldvcpu,
+ unsigned int newvcpu,
+ const char *reason,
+ bool success);
void qemuDomainSecurityLabelAudit(virDomainObjPtr vm, bool success);
#endif /* __QEMU_AUDIT_H__ */
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index c2ddd34..65dfa5f 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -1605,6 +1605,8 @@ static int qemudDomainSetMemory(virDomainPtr dom, unsigned long
newmem) {
qemuDomainObjEnterMonitor(vm);
r = qemuMonitorSetBalloon(priv->mon, newmem);
qemuDomainObjExitMonitor(vm);
+ qemuDomainMemoryAudit(vm, vm->def->mem.cur_balloon, newmem,
"update",
+ r == 1);
if (r < 0)
goto endjob;
@@ -1615,6 +1617,7 @@ static int qemudDomainSetMemory(virDomainPtr dom, unsigned long
newmem) {
goto endjob;
}
+ /* XXX update vm->def->mem.cur_balloon? */
The reason we don't update cur_balloon, is that all we're
doing here is making a *request* to guest OS change its
balloon level. The guest is under no obligation to comply
and if it does comply it may not reach the requested level
immediately. Hence we always talk to the guest to get an
update at time of query instead.
ret = 0;
endjob:
if (qemuDomainObjEndJob(vm) == 0)
@@ -2518,8 +2521,9 @@ static void processWatchdogEvent(void *data, void *opaque)
static int qemudDomainHotplugVcpus(virDomainObjPtr vm, unsigned int nvcpus)
{
qemuDomainObjPrivatePtr priv = vm->privateData;
- int i, rc;
+ int i, rc = 1;
int ret = -1;
+ int oldvcpus = vm->def->vcpus;
qemuDomainObjEnterMonitor(vm);
@@ -2554,6 +2558,7 @@ static int qemudDomainHotplugVcpus(virDomainObjPtr vm, unsigned int
nvcpus)
cleanup:
qemuDomainObjExitMonitor(vm);
+ qemuDomainVcpuAudit(vm, oldvcpus, nvcpus, "update", rc == 1);
return ret;
unsupported:
ACK
Daniel
--
|:
http://berrange.com -o-
http://www.flickr.com/photos/dberrange/ :|
|:
http://libvirt.org -o-
http://virt-manager.org :|
|:
http://autobuild.org -o-
http://search.cpan.org/~danberr/ :|
|:
http://entangle-photo.org -o-
http://live.gnome.org/gtk-vnc :|