int nodeDeviceListCaps(virNodeDevicePtr dev, char **const names, int maxnames) { virNodeDeviceObjPtr obj; virNodeDevCapsDefPtr caps; int ncaps = 0; int ret = -1; nodeDeviceLock(); obj = virNodeDeviceFindByName(&driver->devs, dev->name); nodeDeviceUnlock(); if (!obj) { virReportError(VIR_ERR_NO_NODE_DEVICE, _("no node device with matching name '%s'"), dev->name); goto cleanup; } if (virNodeDeviceListCapsEnsureACL(dev->conn, obj->def) < 0) goto cleanup; for (caps = obj->def->caps; caps && ncaps < maxnames; caps = caps->next) { if (VIR_STRDUP(names[ncaps++], virNodeDevCapTypeToString(caps->data.type)) < 0) goto cleanup; if (caps->data.type == VIR_NODE_DEV_CAP_SCSI_HOST) { if (ncaps < maxnames && caps->data.scsi_host.flags & VIR_NODE_DEV_CAP_FLAG_HBA_FC_HOST) { if (VIR_STRDUP(names[ncaps++], virNodeDevCapTypeToString(VIR_NODE_DEV_CAP_FC_HOST)) < 0) goto cleanup; } if (ncaps < maxnames && caps->data.scsi_host.flags & VIR_NODE_DEV_CAP_FLAG_HBA_VPORT_OPS) { if (VIR_STRDUP(names[ncaps++], virNodeDevCapTypeToString(VIR_NODE_DEV_CAP_VPORTS)) < 0) goto cleanup; } } } ret = ncaps; cleanup: if (obj) virNodeDeviceObjUnlock(obj); if (ret == -1) { --ncaps; while (--ncaps >= 0) VIR_FREE(names[ncaps]); } return ret; }
static bool virNodeDeviceObjHasCap(const virNodeDeviceObj *obj, const char *cap) { virNodeDevCapsDefPtr caps = obj->def->caps; const char *fc_host_cap = virNodeDevCapTypeToString(VIR_NODE_DEV_CAP_FC_HOST); const char *vports_cap = virNodeDevCapTypeToString(VIR_NODE_DEV_CAP_VPORTS); const char *mdev_types = virNodeDevCapTypeToString(VIR_NODE_DEV_CAP_MDEV_TYPES); while (caps) { if (STREQ(cap, virNodeDevCapTypeToString(caps->data.type))) { return true; } else { switch (caps->data.type) { case VIR_NODE_DEV_CAP_PCI_DEV: if ((STREQ(cap, mdev_types)) && (caps->data.pci_dev.flags & VIR_NODE_DEV_CAP_FLAG_PCI_MDEV)) return true; break; case VIR_NODE_DEV_CAP_SCSI_HOST: if ((STREQ(cap, fc_host_cap) && (caps->data.scsi_host.flags & VIR_NODE_DEV_CAP_FLAG_HBA_FC_HOST)) || (STREQ(cap, vports_cap) && (caps->data.scsi_host.flags & VIR_NODE_DEV_CAP_FLAG_HBA_VPORT_OPS))) return true; break; case VIR_NODE_DEV_CAP_SYSTEM: case VIR_NODE_DEV_CAP_USB_DEV: case VIR_NODE_DEV_CAP_USB_INTERFACE: case VIR_NODE_DEV_CAP_NET: case VIR_NODE_DEV_CAP_SCSI_TARGET: case VIR_NODE_DEV_CAP_SCSI: case VIR_NODE_DEV_CAP_STORAGE: case VIR_NODE_DEV_CAP_FC_HOST: case VIR_NODE_DEV_CAP_VPORTS: case VIR_NODE_DEV_CAP_SCSI_GENERIC: case VIR_NODE_DEV_CAP_DRM: case VIR_NODE_DEV_CAP_MDEV_TYPES: case VIR_NODE_DEV_CAP_MDEV: case VIR_NODE_DEV_CAP_CCW_DEV: case VIR_NODE_DEV_CAP_LAST: break; } } caps = caps->next; } return false; }
int nodeDeviceListCaps(virNodeDevicePtr dev, char **const names, int maxnames) { virNodeDeviceObjPtr obj; virNodeDeviceDefPtr def; virNodeDevCapsDefPtr caps; int ncaps = 0; int ret = -1; if (!(obj = nodeDeviceObjFindByName(dev->name))) return -1; def = virNodeDeviceObjGetDef(obj); if (virNodeDeviceListCapsEnsureACL(dev->conn, def) < 0) goto cleanup; for (caps = def->caps; caps && ncaps < maxnames; caps = caps->next) { if (VIR_STRDUP(names[ncaps++], virNodeDevCapTypeToString(caps->data.type)) < 0) goto cleanup; if (caps->data.type == VIR_NODE_DEV_CAP_SCSI_HOST) { if (ncaps < maxnames && caps->data.scsi_host.flags & VIR_NODE_DEV_CAP_FLAG_HBA_FC_HOST) { if (VIR_STRDUP(names[ncaps++], virNodeDevCapTypeToString(VIR_NODE_DEV_CAP_FC_HOST)) < 0) goto cleanup; } if (ncaps < maxnames && caps->data.scsi_host.flags & VIR_NODE_DEV_CAP_FLAG_HBA_VPORT_OPS) { if (VIR_STRDUP(names[ncaps++], virNodeDevCapTypeToString(VIR_NODE_DEV_CAP_VPORTS)) < 0) goto cleanup; } } } ret = ncaps; cleanup: virNodeDeviceObjUnlock(obj); if (ret == -1) { --ncaps; while (--ncaps >= 0) VIR_FREE(names[ncaps]); } return ret; }
int virNodeDeviceHasCap(const virNodeDeviceObjPtr dev, const char *cap) { virNodeDevCapsDefPtr caps = dev->def->caps; while (caps) { if (STREQ(cap, virNodeDevCapTypeToString(caps->type))) return 1; caps = caps->next; } return 0; }
int nodeDeviceListCaps(virNodeDevicePtr dev, char **const names, int maxnames) { virNodeDeviceDriverStatePtr driver = dev->conn->nodeDevicePrivateData; virNodeDeviceObjPtr obj; virNodeDevCapsDefPtr caps; int ncaps = 0; int ret = -1; nodeDeviceLock(driver); obj = virNodeDeviceFindByName(&driver->devs, dev->name); nodeDeviceUnlock(driver); if (!obj) { virReportError(VIR_ERR_NO_NODE_DEVICE, _("no node device with matching name '%s'"), dev->name); goto cleanup; } if (virNodeDeviceListCapsEnsureACL(dev->conn, obj->def) < 0) goto cleanup; for (caps = obj->def->caps; caps && ncaps < maxnames; caps = caps->next) { if (VIR_STRDUP(names[ncaps++], virNodeDevCapTypeToString(caps->type)) < 0) goto cleanup; } ret = ncaps; cleanup: if (obj) virNodeDeviceObjUnlock(obj); if (ret == -1) { --ncaps; while (--ncaps >= 0) VIR_FREE(names[ncaps]); } return ret; }
static int nodeDeviceListCaps(virNodeDevicePtr dev, char **const names, int maxnames) { virDeviceMonitorStatePtr driver = dev->conn->devMonPrivateData; virNodeDeviceObjPtr obj; virNodeDevCapsDefPtr caps; int ncaps = 0; int ret = -1; nodeDeviceLock(driver); obj = virNodeDeviceFindByName(&driver->devs, dev->name); nodeDeviceUnlock(driver); if (!obj) { virNodeDeviceReportError(VIR_ERR_NO_NODE_DEVICE, _("no node device with matching name '%s'"), dev->name); goto cleanup; } for (caps = obj->def->caps; caps && ncaps < maxnames; caps = caps->next) { names[ncaps] = strdup(virNodeDevCapTypeToString(caps->type)); if (names[ncaps++] == NULL) { virReportOOMError(); goto cleanup; } } ret = ncaps; cleanup: if (obj) virNodeDeviceObjUnlock(obj); if (ret == -1) { --ncaps; while (--ncaps >= 0) VIR_FREE(names[ncaps]); } return ret; }
char *virNodeDeviceDefFormat(const virNodeDeviceDefPtr def) { virBuffer buf = VIR_BUFFER_INITIALIZER; virNodeDevCapsDefPtr caps; unsigned int i = 0; virBufferAddLit(&buf, "<device>\n"); virBufferEscapeString(&buf, " <name>%s</name>\n", def->name); if (def->parent) { virBufferEscapeString(&buf, " <parent>%s</parent>\n", def->parent); } if (def->driver) { virBufferAddLit(&buf, " <driver>\n"); virBufferEscapeString(&buf, " <name>%s</name>\n", def->driver); virBufferAddLit(&buf, " </driver>\n"); } for (caps = def->caps; caps; caps = caps->next) { char uuidstr[VIR_UUID_STRING_BUFLEN]; union _virNodeDevCapData *data = &caps->data; virBufferVSprintf(&buf, " <capability type='%s'>\n", virNodeDevCapTypeToString(caps->type)); switch (caps->type) { case VIR_NODE_DEV_CAP_SYSTEM: if (data->system.product_name) virBufferEscapeString(&buf, " <product>%s</product>\n", data->system.product_name); virBufferAddLit(&buf, " <hardware>\n"); if (data->system.hardware.vendor_name) virBufferEscapeString(&buf, " <vendor>%s</vendor>\n", data->system.hardware.vendor_name); if (data->system.hardware.version) virBufferEscapeString(&buf, " <version>%s</version>\n", data->system.hardware.version); if (data->system.hardware.serial) virBufferEscapeString(&buf, " <serial>%s</serial>\n", data->system.hardware.serial); virUUIDFormat(data->system.hardware.uuid, uuidstr); virBufferVSprintf(&buf, " <uuid>%s</uuid>\n", uuidstr); virBufferAddLit(&buf, " </hardware>\n"); virBufferAddLit(&buf, " <firmware>\n"); if (data->system.firmware.vendor_name) virBufferEscapeString(&buf, " <vendor>%s</vendor>\n", data->system.firmware.vendor_name); if (data->system.firmware.version) virBufferEscapeString(&buf, " <version>%s</version>\n", data->system.firmware.version); if (data->system.firmware.release_date) virBufferEscapeString(&buf, " <release_date>%s</release_date>\n", data->system.firmware.release_date); virBufferAddLit(&buf, " </firmware>\n"); break; case VIR_NODE_DEV_CAP_PCI_DEV: virBufferVSprintf(&buf, " <domain>%d</domain>\n", data->pci_dev.domain); virBufferVSprintf(&buf, " <bus>%d</bus>\n", data->pci_dev.bus); virBufferVSprintf(&buf, " <slot>%d</slot>\n", data->pci_dev.slot); virBufferVSprintf(&buf, " <function>%d</function>\n", data->pci_dev.function); virBufferVSprintf(&buf, " <product id='0x%04x'", data->pci_dev.product); if (data->pci_dev.product_name) virBufferEscapeString(&buf, ">%s</product>\n", data->pci_dev.product_name); else virBufferAddLit(&buf, " />\n"); virBufferVSprintf(&buf, " <vendor id='0x%04x'", data->pci_dev.vendor); if (data->pci_dev.vendor_name) virBufferEscapeString(&buf, ">%s</vendor>\n", data->pci_dev.vendor_name); else virBufferAddLit(&buf, " />\n"); if (data->pci_dev.flags & VIR_NODE_DEV_CAP_FLAG_PCI_PHYSICAL_FUNCTION) { virBufferAddLit(&buf, " <capability type='phys_function'>\n"); virBufferVSprintf(&buf, " <address domain='0x%.4x' bus='0x%.2x' " "slot='0x%.2x' function='0x%.1x'/>\n", data->pci_dev.physical_function->domain, data->pci_dev.physical_function->bus, data->pci_dev.physical_function->slot, data->pci_dev.physical_function->function); virBufferAddLit(&buf, " </capability>\n"); } if (data->pci_dev.flags & VIR_NODE_DEV_CAP_FLAG_PCI_VIRTUAL_FUNCTION) { virBufferAddLit(&buf, " <capability type='virt_functions'>\n"); for (i = 0 ; i < data->pci_dev.num_virtual_functions ; i++) { virBufferVSprintf(&buf, " <address domain='0x%.4x' bus='0x%.2x' " "slot='0x%.2x' function='0x%.1x'/>\n", data->pci_dev.virtual_functions[i]->domain, data->pci_dev.virtual_functions[i]->bus, data->pci_dev.virtual_functions[i]->slot, data->pci_dev.virtual_functions[i]->function); } virBufferAddLit(&buf, " </capability>\n"); } break; case VIR_NODE_DEV_CAP_USB_DEV: virBufferVSprintf(&buf, " <bus>%d</bus>\n", data->usb_dev.bus); virBufferVSprintf(&buf, " <device>%d</device>\n", data->usb_dev.device); virBufferVSprintf(&buf, " <product id='0x%04x'", data->usb_dev.product); if (data->usb_dev.product_name) virBufferEscapeString(&buf, ">%s</product>\n", data->usb_dev.product_name); else virBufferAddLit(&buf, " />\n"); virBufferVSprintf(&buf, " <vendor id='0x%04x'", data->usb_dev.vendor); if (data->usb_dev.vendor_name) virBufferEscapeString(&buf, ">%s</vendor>\n", data->usb_dev.vendor_name); else virBufferAddLit(&buf, " />\n"); break; case VIR_NODE_DEV_CAP_USB_INTERFACE: virBufferVSprintf(&buf, " <number>%d</number>\n", data->usb_if.number); virBufferVSprintf(&buf, " <class>%d</class>\n", data->usb_if._class); virBufferVSprintf(&buf, " <subclass>%d</subclass>\n", data->usb_if.subclass); virBufferVSprintf(&buf, " <protocol>%d</protocol>\n", data->usb_if.protocol); if (data->usb_if.description) virBufferEscapeString(&buf, " <description>%s</description>\n", data->usb_if.description); break; case VIR_NODE_DEV_CAP_NET: virBufferEscapeString(&buf, " <interface>%s</interface>\n", data->net.ifname); if (data->net.address) virBufferEscapeString(&buf, " <address>%s</address>\n", data->net.address); if (data->net.subtype != VIR_NODE_DEV_CAP_NET_LAST) { const char *subtyp = virNodeDevNetCapTypeToString(data->net.subtype); virBufferEscapeString(&buf, " <capability type='%s'/>\n", subtyp); } break; case VIR_NODE_DEV_CAP_SCSI_HOST: virBufferVSprintf(&buf, " <host>%d</host>\n", data->scsi_host.host); if (data->scsi_host.flags & VIR_NODE_DEV_CAP_FLAG_HBA_FC_HOST) { virBufferAddLit(&buf, " <capability type='fc_host'>\n"); virBufferEscapeString(&buf, " <wwnn>%s</wwnn>\n", data->scsi_host.wwnn); virBufferEscapeString(&buf, " <wwpn>%s</wwpn>\n", data->scsi_host.wwpn); virBufferAddLit(&buf, " </capability>\n"); } if (data->scsi_host.flags & VIR_NODE_DEV_CAP_FLAG_HBA_VPORT_OPS) { virBufferAddLit(&buf, " <capability type='vport_ops' />\n"); } break; case VIR_NODE_DEV_CAP_SCSI_TARGET: virBufferEscapeString(&buf, " <target>%s</target>\n", data->scsi_target.name); break; case VIR_NODE_DEV_CAP_SCSI: virBufferVSprintf(&buf, " <host>%d</host>\n", data->scsi.host); virBufferVSprintf(&buf, " <bus>%d</bus>\n", data->scsi.bus); virBufferVSprintf(&buf, " <target>%d</target>\n", data->scsi.target); virBufferVSprintf(&buf, " <lun>%d</lun>\n", data->scsi.lun); if (data->scsi.type) virBufferEscapeString(&buf, " <type>%s</type>\n", data->scsi.type); break; case VIR_NODE_DEV_CAP_STORAGE: virBufferEscapeString(&buf, " <block>%s</block>\n", data->storage.block); if (data->storage.bus) virBufferEscapeString(&buf, " <bus>%s</bus>\n", data->storage.bus); if (data->storage.drive_type) virBufferEscapeString(&buf, " <drive_type>%s</drive_type>\n", data->storage.drive_type); if (data->storage.model) virBufferEscapeString(&buf, " <model>%s</model>\n", data->storage.model); if (data->storage.vendor) virBufferEscapeString(&buf, " <vendor>%s</vendor>\n", data->storage.vendor); if (data->storage.serial) virBufferVSprintf(&buf, " <serial>%s</serial>\n", data->storage.serial); if (data->storage.flags & VIR_NODE_DEV_CAP_STORAGE_REMOVABLE) { int avl = data->storage.flags & VIR_NODE_DEV_CAP_STORAGE_REMOVABLE_MEDIA_AVAILABLE; virBufferAddLit(&buf, " <capability type='removable'>\n"); virBufferVSprintf(&buf, " <media_available>%d" "</media_available>\n", avl ? 1 : 0); virBufferVSprintf(&buf, " <media_size>%llu</media_size>\n", data->storage.removable_media_size); if (data->storage.media_label) virBufferEscapeString(&buf, " <media_label>%s</media_label>\n", data->storage.media_label); if (data->storage.logical_block_size > 0) virBufferVSprintf(&buf, " <logical_block_size>%llu" "</logical_block_size>\n", data->storage.logical_block_size); if (data->storage.num_blocks > 0) virBufferVSprintf(&buf, " <num_blocks>%llu</num_blocks>\n", data->storage.num_blocks); virBufferAddLit(&buf, " </capability>\n"); } else { virBufferVSprintf(&buf, " <size>%llu</size>\n", data->storage.size); if (data->storage.logical_block_size > 0) virBufferVSprintf(&buf, " <logical_block_size>%llu" "</logical_block_size>\n", data->storage.logical_block_size); if (data->storage.num_blocks > 0) virBufferVSprintf(&buf, " <num_blocks>%llu</num_blocks>\n", data->storage.num_blocks); } if (data->storage.flags & VIR_NODE_DEV_CAP_STORAGE_HOTPLUGGABLE) virBufferAddLit(&buf, " <capability type='hotpluggable' />\n"); break; case VIR_NODE_DEV_CAP_LAST: /* ignore special LAST value */ break; } virBufferAddLit(&buf, " </capability>\n"); } virBufferAddLit(&buf, "</device>\n"); if (virBufferError(&buf)) goto no_memory; return virBufferContentAndReset(&buf); no_memory: virReportOOMError(); virBufferFreeAndReset(&buf); return NULL; }