[libvirt] [PATCH 7/7] Add disk/net resource auditing to QEMU driver

Daniel P. Berrange berrange at redhat.com
Wed Oct 27 11:36:17 UTC 2010


Add auditing of all initial disk/net assignments to QEMU guests
at startup. Add auditing for all hotplug & unplug events and
disk media changes.

* src/qemu/qemu_driver.c: Add disk/net resource auditing
---
 src/qemu/qemu_driver.c |  111 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 111 insertions(+), 0 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 8db5e7a..b119ca1 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -3668,6 +3668,79 @@ static int qemuDomainSnapshotSetActive(virDomainObjPtr vm,
 static int qemuDomainSnapshotSetInactive(virDomainObjPtr vm,
                                          char *snapshotDir);
 
+static void qemuDomainDiskAudit(virDomainObjPtr vm,
+                                virDomainDiskDefPtr oldDef,
+                                virDomainDiskDefPtr newDef,
+                                const char *reason,
+                                bool success)
+{
+    char uuidstr[VIR_UUID_STRING_BUFLEN];
+    char *vmname;
+    char *oldsrc = NULL;
+    char *newsrc = NULL;
+
+    virUUIDFormat(vm->def->uuid, uuidstr);
+    if (!(vmname = virAuditEncode("vm", vm->def->name))) {
+        VIR_WARN0("OOM while encoding audit message");
+        return;
+    }
+
+    if (!(oldsrc = virAuditEncode("old-disk",
+                                  oldDef && oldDef->src ?
+                                  oldDef->src : "?"))) {
+        VIR_WARN0("OOM while encoding audit message");
+        goto cleanup;
+    }
+    if (!(newsrc = virAuditEncode("new-disk",
+                                  newDef && newDef->src ?
+                                  newDef->src : "?"))) {
+        VIR_WARN0("OOM while encoding audit message");
+        goto cleanup;
+    }
+
+    VIR_AUDIT(VIR_AUDIT_RECORD_RESOURCE, success,
+              "resrc=disk reason=%s %s uuid=%s %s %s",
+              reason, vmname, uuidstr,
+              oldsrc, newsrc);
+
+cleanup:
+    VIR_FREE(vmname);
+    VIR_FREE(oldsrc);
+    VIR_FREE(newsrc);
+}
+
+
+static void qemuDomainNetAudit(virDomainObjPtr vm,
+                               virDomainNetDefPtr oldDef,
+                               virDomainNetDefPtr newDef,
+                               const char *reason,
+                               bool success)
+{
+    char uuidstr[VIR_UUID_STRING_BUFLEN];
+    char newMacstr[VIR_MAC_STRING_BUFLEN];
+    char oldMacstr[VIR_MAC_STRING_BUFLEN];
+    char *vmname;
+
+    virUUIDFormat(vm->def->uuid, uuidstr);
+    if (oldDef)
+        virFormatMacAddr(oldDef->mac, oldMacstr);
+    if (newDef)
+        virFormatMacAddr(newDef->mac, newMacstr);
+    if (!(vmname = virAuditEncode("vm", vm->def->name))) {
+        VIR_WARN0("OOM while encoding audit message");
+        return;
+    }
+
+    VIR_AUDIT(VIR_AUDIT_RECORD_RESOURCE, success,
+              "resrc=net reason=%s %s uuid=%s old-net='%s' new-net='%s'",
+              reason, vmname, uuidstr,
+              oldDef ? oldMacstr : "?",
+              newDef ? newMacstr : "?");
+
+    VIR_FREE(vmname);
+}
+
+
 static void qemuDomainLifecycleAudit(virDomainObjPtr vm,
                                      const char *op,
                                      const char *reason,
@@ -3677,6 +3750,7 @@ static void qemuDomainLifecycleAudit(virDomainObjPtr vm,
     char *vmname;
 
     virUUIDFormat(vm->def->uuid, uuidstr);
+
     if (!(vmname = virAuditEncode("vm", vm->def->name))) {
         VIR_WARN0("OOM while encoding audit message");
         return;
@@ -3690,6 +3764,19 @@ static void qemuDomainLifecycleAudit(virDomainObjPtr vm,
 
 static void qemuDomainStartAudit(virDomainObjPtr vm, const char *reason, bool success)
 {
+    int i;
+
+    for (i = 0 ; i < vm->def->ndisks ; i++) {
+        virDomainDiskDefPtr disk = vm->def->disks[i];
+        if (disk->src) /* Skips CDROM without media initially inserted */
+            qemuDomainDiskAudit(vm, NULL, disk, "start", true);
+    }
+
+    for (i = 0 ; i < vm->def->nnets ; i++) {
+        virDomainNetDefPtr net = vm->def->nets[i];
+        qemuDomainNetAudit(vm, NULL, net, "start", true);
+    }
+
     qemuDomainLifecycleAudit(vm, "start", reason, success);
 }
 
@@ -7565,6 +7652,8 @@ static int qemudDomainChangeEjectableMedia(struct qemud_driver *driver,
     }
     qemuDomainObjExitMonitorWithDriver(driver, vm);
 
+    qemuDomainDiskAudit(vm, origdisk, disk, "update", ret >= 0);
+
     if (ret < 0)
         goto error;
 
@@ -7664,6 +7753,8 @@ static int qemudDomainAttachPciDiskDevice(struct qemud_driver *driver,
     }
     qemuDomainObjExitMonitorWithDriver(driver, vm);
 
+    qemuDomainDiskAudit(vm, NULL, disk, "attach", ret >= 0);
+
     if (ret < 0)
         goto error;
 
@@ -7899,6 +7990,8 @@ static int qemudDomainAttachSCSIDisk(struct qemud_driver *driver,
     }
     qemuDomainObjExitMonitorWithDriver(driver, vm);
 
+    qemuDomainDiskAudit(vm, NULL, disk, "attach", ret >= 0);
+
     if (ret < 0)
         goto error;
 
@@ -7984,6 +8077,8 @@ static int qemudDomainAttachUsbMassstorageDevice(struct qemud_driver *driver,
     }
     qemuDomainObjExitMonitorWithDriver(driver, vm);
 
+    qemuDomainDiskAudit(vm, NULL, disk, "attach", ret >= 0);
+
     if (ret < 0)
         goto error;
 
@@ -8118,11 +8213,13 @@ static int qemudDomainAttachNetDevice(virConnectPtr conn,
         (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE)) {
         if (qemuMonitorAddNetdev(priv->mon, netstr) < 0) {
             qemuDomainObjExitMonitorWithDriver(driver, vm);
+            qemuDomainNetAudit(vm, NULL, net, "attach", false);
             goto try_tapfd_close;
         }
     } else {
         if (qemuMonitorAddHostNetwork(priv->mon, netstr) < 0) {
             qemuDomainObjExitMonitorWithDriver(driver, vm);
+            qemuDomainNetAudit(vm, NULL, net, "attach", false);
             goto try_tapfd_close;
         }
     }
@@ -8150,12 +8247,14 @@ static int qemudDomainAttachNetDevice(virConnectPtr conn,
     if (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) {
         if (qemuMonitorAddDevice(priv->mon, nicstr) < 0) {
             qemuDomainObjExitMonitorWithDriver(driver, vm);
+            qemuDomainNetAudit(vm, NULL, net, "attach", false);
             goto try_remove;
         }
     } else {
         if (qemuMonitorAddPCINetwork(priv->mon, nicstr,
                                      &guestAddr) < 0) {
             qemuDomainObjExitMonitorWithDriver(driver, vm);
+            qemuDomainNetAudit(vm, NULL, net, "attach", false);
             goto try_remove;
         }
         net->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
@@ -8163,6 +8262,8 @@ static int qemudDomainAttachNetDevice(virConnectPtr conn,
     }
     qemuDomainObjExitMonitorWithDriver(driver, vm);
 
+    qemuDomainNetAudit(vm, NULL, net, "attach", true);
+
     ret = 0;
 
     vm->def->nets[vm->def->nnets++] = net;
@@ -8860,6 +8961,8 @@ static int qemudDomainDetachPciDiskDevice(struct qemud_driver *driver,
     }
     qemuDomainObjExitMonitorWithDriver(driver, vm);
 
+    qemuDomainDiskAudit(vm, detach, NULL, "detach", ret >= 0);
+
     if ((qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) &&
         qemuDomainPCIAddressReleaseAddr(priv->pciaddrs, &detach->info) < 0)
         VIR_WARN("Unable to release PCI address on %s", dev->data.disk->src);
@@ -8928,6 +9031,8 @@ static int qemudDomainDetachSCSIDiskDevice(struct qemud_driver *driver,
     }
     qemuDomainObjExitMonitorWithDriver(driver, vm);
 
+    qemuDomainDiskAudit(vm, detach, NULL, "detach", ret >= 0);
+
     virDomainDiskRemove(vm->def, i);
 
     virDomainDiskDefFree(detach);
@@ -9081,12 +9186,14 @@ qemudDomainDetachNetDevice(struct qemud_driver *driver,
     if (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) {
         if (qemuMonitorDelDevice(priv->mon, detach->info.alias) < 0) {
             qemuDomainObjExitMonitor(vm);
+            qemuDomainNetAudit(vm, detach, NULL, "detach", false);
             goto cleanup;
         }
     } else {
         if (qemuMonitorRemovePCIDevice(priv->mon,
                                        &detach->info.addr.pci) < 0) {
             qemuDomainObjExitMonitorWithDriver(driver, vm);
+            qemuDomainNetAudit(vm, detach, NULL, "detach", false);
             goto cleanup;
         }
     }
@@ -9095,16 +9202,20 @@ qemudDomainDetachNetDevice(struct qemud_driver *driver,
         (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE)) {
         if (qemuMonitorRemoveNetdev(priv->mon, hostnet_name) < 0) {
             qemuDomainObjExitMonitorWithDriver(driver, vm);
+            qemuDomainNetAudit(vm, detach, NULL, "detach", false);
             goto cleanup;
         }
     } else {
         if (qemuMonitorRemoveHostNetwork(priv->mon, vlan, hostnet_name) < 0) {
             qemuDomainObjExitMonitorWithDriver(driver, vm);
+            qemuDomainNetAudit(vm, detach, NULL, "detach", false);
             goto cleanup;
         }
     }
     qemuDomainObjExitMonitorWithDriver(driver, vm);
 
+    qemuDomainNetAudit(vm, detach, NULL, "detach", true);
+
     if ((qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) &&
         qemuDomainPCIAddressReleaseAddr(priv->pciaddrs, &detach->info) < 0)
         VIR_WARN0("Unable to release PCI address on NIC");
-- 
1.7.2.3




More information about the libvir-list mailing list