Introduce a src/libvirt-nodedev.c file to hold all the methods related to the virNodeDevice type. --- docs/apibuild.py | 1 + src/Makefile.am | 2 + src/libvirt-nodedev.c | 756 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/libvirt.c | 728 ------------------------------------------------ 4 files changed, 759 insertions(+), 728 deletions(-) create mode 100644 src/libvirt-nodedev.c diff --git a/docs/apibuild.py b/docs/apibuild.py index 2780e7a..cf329e2 100755 --- a/docs/apibuild.py +++ b/docs/apibuild.py @@ -27,6 +27,7 @@ included_files = { "libvirt-domain-snapshot.c": "Domain snapshot interfaces for the libvirt library", "libvirt-interface.c": "Interface interfaces for the libvirt library", "libvirt-network.c": "Network interfaces for the libvirt library", + "libvirt-nodedev.c": "Node device interfaces for the libvirt library", "libvirt-nwfilter.c": "NWFilter interfaces for the libvirt library", "virerror.c": "implements error handling and reporting code for libvirt", "virevent.c": "event loop for monitoring file handles", diff --git a/src/Makefile.am b/src/Makefile.am index 98d261a..dfc5920 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -192,6 +192,7 @@ DRIVER_SOURCES = \ libvirt-domain-snapshot.c \ libvirt-interface.c \ libvirt-network.c \ + libvirt-nodedev.c \ libvirt-nwfilter.c \ locking/lock_manager.c locking/lock_manager.h \ locking/lock_driver.h \ @@ -2193,6 +2194,7 @@ libvirt_setuid_rpc_client_la_SOURCES = \ libvirt-domain-snapshot.c \ libvirt-interface.c \ libvirt-network.c \ + libvirt-nodedev.c \ libvirt-nwfilter.c \ libvirt-lxc.c \ $(NULL) diff --git a/src/libvirt-nodedev.c b/src/libvirt-nodedev.c new file mode 100644 index 0000000..f8d5ae1 --- /dev/null +++ b/src/libvirt-nodedev.c @@ -0,0 +1,756 @@ +/* + * libvirt-nodedev.c: entry points for virNodeDevPtr APIs + * + * Copyright (C) 2006-2014 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <http://www.gnu.org/licenses/>. + */ + +#include <config.h> + +#include "datatypes.h" +#include "virlog.h" + +VIR_LOG_INIT("libvirt.nodedev"); + +#define VIR_FROM_THIS VIR_FROM_NONE + + +/** + * virNodeNumOfDevices: + * @conn: pointer to the hypervisor connection + * @cap: capability name + * @flags: extra flags; not used yet, so callers should always pass 0 + * + * Provides the number of node devices. + * + * If the optional 'cap' argument is non-NULL, then the count + * will be restricted to devices with the specified capability + * + * Returns the number of node devices or -1 in case of error + */ +int +virNodeNumOfDevices(virConnectPtr conn, const char *cap, unsigned int flags) +{ + VIR_DEBUG("conn=%p, cap=%s, flags=%x", conn, NULLSTR(cap), flags); + + virResetLastError(); + + virCheckConnectReturn(conn, -1); + + if (conn->nodeDeviceDriver && conn->nodeDeviceDriver->nodeNumOfDevices) { + int ret; + ret = conn->nodeDeviceDriver->nodeNumOfDevices(conn, cap, flags); + if (ret < 0) + goto error; + return ret; + } + + virReportUnsupportedError(); + + error: + virDispatchError(conn); + return -1; +} + + +/** + * virConnectListAllNodeDevices: + * @conn: Pointer to the hypervisor connection. + * @devices: Pointer to a variable to store the array containing the node + * device objects or NULL if the list is not required (just returns + * number of node devices). + * @flags: bitwise-OR of virConnectListAllNodeDevices. + * + * Collect the list of node devices, and allocate an array to store those + * objects. + * + * Normally, all node devices are returned; however, @flags can be used to + * filter the results for a smaller list of targeted node devices. The valid + * flags are divided into groups, where each group contains bits that + * describe mutually exclusive attributes of a node device, and where all bits + * within a group describe all possible node devices. + * + * Only one group of the @flags is provided to filter the node devices by + * capability type, flags include: + * VIR_CONNECT_LIST_NODE_DEVICES_CAP_SYSTEM + * VIR_CONNECT_LIST_NODE_DEVICES_CAP_PCI_DEV + * VIR_CONNECT_LIST_NODE_DEVICES_CAP_USB_DEV + * VIR_CONNECT_LIST_NODE_DEVICES_CAP_USB_INTERFACE + * VIR_CONNECT_LIST_NODE_DEVICES_CAP_NET + * VIR_CONNECT_LIST_NODE_DEVICES_CAP_SCSI_HOST + * VIR_CONNECT_LIST_NODE_DEVICES_CAP_SCSI_TARGET + * VIR_CONNECT_LIST_NODE_DEVICES_CAP_SCSI + * VIR_CONNECT_LIST_NODE_DEVICES_CAP_STORAGE + * VIR_CONNECT_LIST_NODE_DEVICES_CAP_FC_HOST + * VIR_CONNECT_LIST_NODE_DEVICES_CAP_VPORTS + * VIR_CONNECT_LIST_NODE_DEVICES_CAP_SCSI_GENERIC + * + * Returns the number of node devices found or -1 and sets @devices to NULL in + * case of error. On success, the array stored into @devices is guaranteed to + * have an extra allocated element set to NULL but not included in the return + * count, to make iteration easier. The caller is responsible for calling + * virNodeDeviceFree() on each array element, then calling free() on + * @devices. + */ +int +virConnectListAllNodeDevices(virConnectPtr conn, + virNodeDevicePtr **devices, + unsigned int flags) +{ + VIR_DEBUG("conn=%p, devices=%p, flags=%x", conn, devices, flags); + + virResetLastError(); + + if (devices) + *devices = NULL; + + virCheckConnectReturn(conn, -1); + + if (conn->nodeDeviceDriver && + conn->nodeDeviceDriver->connectListAllNodeDevices) { + int ret; + ret = conn->nodeDeviceDriver->connectListAllNodeDevices(conn, devices, flags); + if (ret < 0) + goto error; + return ret; + } + + virReportUnsupportedError(); + + error: + virDispatchError(conn); + return -1; +} + + +/** + * virNodeListDevices: + * @conn: pointer to the hypervisor connection + * @cap: capability name + * @names: array to collect the list of node device names + * @maxnames: size of @names + * @flags: extra flags; not used yet, so callers should always pass 0 + * + * Collect the list of node devices, and store their names in @names + * + * For more control over the results, see virConnectListAllNodeDevices(). + * + * If the optional 'cap' argument is non-NULL, then the count + * will be restricted to devices with the specified capability + * + * Returns the number of node devices found or -1 in case of error + */ +int +virNodeListDevices(virConnectPtr conn, + const char *cap, + char **const names, int maxnames, + unsigned int flags) +{ + VIR_DEBUG("conn=%p, cap=%s, names=%p, maxnames=%d, flags=%x", + conn, cap, names, maxnames, flags); + + virResetLastError(); + + virCheckConnectReturn(conn, -1); + virCheckNonNullArgGoto(names, error); + virCheckNonNegativeArgGoto(maxnames, error); + + if (conn->nodeDeviceDriver && conn->nodeDeviceDriver->nodeListDevices) { + int ret; + ret = conn->nodeDeviceDriver->nodeListDevices(conn, cap, names, maxnames, flags); + if (ret < 0) + goto error; + return ret; + } + + virReportUnsupportedError(); + + error: + virDispatchError(conn); + return -1; +} + + +/** + * virNodeDeviceLookupByName: + * @conn: pointer to the hypervisor connection + * @name: unique device name + * + * Lookup a node device by its name. + * + * virNodeDeviceFree should be used to free the resources after the + * node device object is no longer needed. + * + * Returns a virNodeDevicePtr if found, NULL otherwise. + */ +virNodeDevicePtr +virNodeDeviceLookupByName(virConnectPtr conn, const char *name) +{ + VIR_DEBUG("conn=%p, name=%p", conn, name); + + virResetLastError(); + + virCheckConnectReturn(conn, NULL); + virCheckNonNullArgGoto(name, error); + + if (conn->nodeDeviceDriver && conn->nodeDeviceDriver->nodeDeviceLookupByName) { + virNodeDevicePtr ret; + ret = conn->nodeDeviceDriver->nodeDeviceLookupByName(conn, name); + if (!ret) + goto error; + return ret; + } + + virReportUnsupportedError(); + + error: + virDispatchError(conn); + return NULL; +} + + +/** + * virNodeDeviceLookupSCSIHostByWWN: + * @conn: pointer to the hypervisor connection + * @wwnn: WWNN of the SCSI Host. + * @wwpn: WWPN of the SCSI Host. + * @flags: extra flags; not used yet, so callers should always pass 0 + * + * Lookup SCSI Host which is capable with 'fc_host' by its WWNN and WWPN. + * + * virNodeDeviceFree should be used to free the resources after the + * node device object is no longer needed. + * + * Returns a virNodeDevicePtr if found, NULL otherwise. + */ +virNodeDevicePtr +virNodeDeviceLookupSCSIHostByWWN(virConnectPtr conn, + const char *wwnn, + const char *wwpn, + unsigned int flags) +{ + VIR_DEBUG("conn=%p, wwnn=%p, wwpn=%p, flags=%x", conn, wwnn, wwpn, flags); + + virResetLastError(); + + virCheckConnectReturn(conn, NULL); + virCheckNonNullArgGoto(wwnn, error); + virCheckNonNullArgGoto(wwpn, error); + + if (conn->nodeDeviceDriver && + conn->nodeDeviceDriver->nodeDeviceLookupSCSIHostByWWN) { + virNodeDevicePtr ret; + ret = conn->nodeDeviceDriver->nodeDeviceLookupSCSIHostByWWN(conn, wwnn, + wwpn, flags); + if (!ret) + goto error; + return ret; + } + + virReportUnsupportedError(); + + error: + virDispatchError(conn); + return NULL; +} + + +/** + * virNodeDeviceGetXMLDesc: + * @dev: pointer to the node device + * @flags: extra flags; not used yet, so callers should always pass 0 + * + * Fetch an XML document describing all aspects of + * the device. + * + * Returns the XML document, or NULL on error + */ +char * +virNodeDeviceGetXMLDesc(virNodeDevicePtr dev, unsigned int flags) +{ + VIR_DEBUG("dev=%p, conn=%p, flags=%x", dev, dev ? dev->conn : NULL, flags); + + virResetLastError(); + + virCheckNodeDeviceReturn(dev, NULL); + + if (dev->conn->nodeDeviceDriver && dev->conn->nodeDeviceDriver->nodeDeviceGetXMLDesc) { + char *ret; + ret = dev->conn->nodeDeviceDriver->nodeDeviceGetXMLDesc(dev, flags); + if (!ret) + goto error; + return ret; + } + + virReportUnsupportedError(); + + error: + virDispatchError(dev->conn); + return NULL; +} + + +/** + * virNodeDeviceGetName: + * @dev: the device + * + * Just return the device name + * + * Returns the device name or NULL in case of error + */ +const char * +virNodeDeviceGetName(virNodeDevicePtr dev) +{ + VIR_DEBUG("dev=%p, conn=%p", dev, dev ? dev->conn : NULL); + + virResetLastError(); + + virCheckNodeDeviceReturn(dev, NULL); + + return dev->name; +} + + +/** + * virNodeDeviceGetParent: + * @dev: the device + * + * Accessor for the parent of the device + * + * Returns the name of the device's parent, or NULL if an + * error occurred or when the device has no parent. + */ +const char * +virNodeDeviceGetParent(virNodeDevicePtr dev) +{ + VIR_DEBUG("dev=%p, conn=%p", dev, dev ? dev->conn : NULL); + + virResetLastError(); + + virCheckNodeDeviceReturn(dev, NULL); + + if (!dev->parent) { + if (dev->conn->nodeDeviceDriver && dev->conn->nodeDeviceDriver->nodeDeviceGetParent) { + dev->parent = dev->conn->nodeDeviceDriver->nodeDeviceGetParent(dev); + } else { + virReportUnsupportedError(); + virDispatchError(dev->conn); + return NULL; + } + } + return dev->parent; +} + + +/** + * virNodeDeviceNumOfCaps: + * @dev: the device + * + * Accessor for the number of capabilities supported by the device. + * + * Returns the number of capabilities supported by the device or -1 + * in case of error. + */ +int +virNodeDeviceNumOfCaps(virNodeDevicePtr dev) +{ + VIR_DEBUG("dev=%p, conn=%p", dev, dev ? dev->conn : NULL); + + virResetLastError(); + + virCheckNodeDeviceReturn(dev, -1); + + if (dev->conn->nodeDeviceDriver && dev->conn->nodeDeviceDriver->nodeDeviceNumOfCaps) { + int ret; + ret = dev->conn->nodeDeviceDriver->nodeDeviceNumOfCaps(dev); + if (ret < 0) + goto error; + return ret; + } + + virReportUnsupportedError(); + + error: + virDispatchError(dev->conn); + return -1; +} + + +/** + * virNodeDeviceListCaps: + * @dev: the device + * @names: array to collect the list of capability names + * @maxnames: size of @names + * + * Lists the names of the capabilities supported by the device. + * + * Returns the number of capability names listed in @names or -1 + * in case of error. + */ +int +virNodeDeviceListCaps(virNodeDevicePtr dev, + char **const names, + int maxnames) +{ + VIR_DEBUG("dev=%p, conn=%p, names=%p, maxnames=%d", + dev, dev ? dev->conn : NULL, names, maxnames); + + virResetLastError(); + + virCheckNodeDeviceReturn(dev, -1); + virCheckNonNullArgGoto(names, error); + virCheckNonNegativeArgGoto(maxnames, error); + + if (dev->conn->nodeDeviceDriver && dev->conn->nodeDeviceDriver->nodeDeviceListCaps) { + int ret; + ret = dev->conn->nodeDeviceDriver->nodeDeviceListCaps(dev, names, maxnames); + if (ret < 0) + goto error; + return ret; + } + + virReportUnsupportedError(); + + error: + virDispatchError(dev->conn); + return -1; +} + + +/** + * virNodeDeviceFree: + * @dev: pointer to the node device + * + * Drops a reference to the node device, freeing it if + * this was the last reference. + * + * Returns the 0 for success, -1 for error. + */ +int +virNodeDeviceFree(virNodeDevicePtr dev) +{ + VIR_DEBUG("dev=%p, conn=%p", dev, dev ? dev->conn : NULL); + + virResetLastError(); + + virCheckNodeDeviceReturn(dev, -1); + + virObjectUnref(dev); + return 0; +} + + +/** + * virNodeDeviceRef: + * @dev: the dev to hold a reference on + * + * Increment the reference count on the dev. For each + * additional call to this method, there shall be a corresponding + * call to virNodeDeviceFree to release the reference count, once + * the caller no longer needs the reference to this object. + * + * This method is typically useful for applications where multiple + * threads are using a connection, and it is required that the + * connection remain open until all threads have finished using + * it. ie, each new thread using a dev would increment + * the reference count. + * + * Returns 0 in case of success, -1 in case of failure. + */ +int +virNodeDeviceRef(virNodeDevicePtr dev) +{ + VIR_DEBUG("dev=%p refs=%d", dev, dev ? dev->object.u.s.refs : 0); + + virResetLastError(); + + virCheckNodeDeviceReturn(dev, -1); + + virObjectRef(dev); + return 0; +} + + +/** + * virNodeDeviceDettach: + * @dev: pointer to the node device + * + * Dettach the node device from the node itself so that it may be + * assigned to a guest domain. + * + * Depending on the hypervisor, this may involve operations such + * as unbinding any device drivers from the device, binding the + * device to a dummy device driver and resetting the device. + * + * If the device is currently in use by the node, this method may + * fail. + * + * Once the device is not assigned to any guest, it may be re-attached + * to the node using the virNodeDeviceReattach() method. + * + * If the caller needs control over which backend driver will be used + * during PCI device assignment (to use something other than the + * default, for example VFIO), the newer virNodeDeviceDetachFlags() + * API should be used instead. + * + * Returns 0 in case of success, -1 in case of failure. + */ +int +virNodeDeviceDettach(virNodeDevicePtr dev) +{ + VIR_DEBUG("dev=%p, conn=%p", dev, dev ? dev->conn : NULL); + + virResetLastError(); + + virCheckNodeDeviceReturn(dev, -1); + virCheckReadOnlyGoto(dev->conn->flags, error); + + if (dev->conn->driver->nodeDeviceDettach) { + int ret; + ret = dev->conn->driver->nodeDeviceDettach(dev); + if (ret < 0) + goto error; + return ret; + } + + virReportUnsupportedError(); + + error: + virDispatchError(dev->conn); + return -1; +} + + +/** + * virNodeDeviceDetachFlags: + * @dev: pointer to the node device + * @driverName: name of backend driver that will be used + * for later device assignment to a domain. NULL + * means "use the hypervisor default driver" + * @flags: extra flags; not used yet, so callers should always pass 0 + * + * Detach the node device from the node itself so that it may be + * assigned to a guest domain. + * + * Depending on the hypervisor, this may involve operations such as + * unbinding any device drivers from the device, binding the device to + * a dummy device driver and resetting the device. Different backend + * drivers expect the device to be bound to different dummy + * devices. For example, QEMU's "kvm" backend driver (the default) + * expects the device to be bound to "pci-stub", but its "vfio" + * backend driver expects the device to be bound to "vfio-pci". + * + * If the device is currently in use by the node, this method may + * fail. + * + * Once the device is not assigned to any guest, it may be re-attached + * to the node using the virNodeDeviceReAttach() method. + * + * Returns 0 in case of success, -1 in case of failure. + */ +int +virNodeDeviceDetachFlags(virNodeDevicePtr dev, + const char *driverName, + unsigned int flags) +{ + VIR_DEBUG("dev=%p, conn=%p driverName=%s flags=%x", + dev, dev ? dev->conn : NULL, + driverName ? driverName : "(default)", flags); + + virResetLastError(); + + virCheckNodeDeviceReturn(dev, -1); + virCheckReadOnlyGoto(dev->conn->flags, error); + + if (dev->conn->driver->nodeDeviceDetachFlags) { + int ret; + ret = dev->conn->driver->nodeDeviceDetachFlags(dev, driverName, flags); + if (ret < 0) + goto error; + return ret; + } + + virReportUnsupportedError(); + + error: + virDispatchError(dev->conn); + return -1; +} + + +/** + * virNodeDeviceReAttach: + * @dev: pointer to the node device + * + * Re-attach a previously dettached node device to the node so that it + * may be used by the node again. + * + * Depending on the hypervisor, this may involve operations such + * as resetting the device, unbinding it from a dummy device driver + * and binding it to its appropriate driver. + * + * If the device is currently in use by a guest, this method may fail. + * + * Returns 0 in case of success, -1 in case of failure. + */ +int +virNodeDeviceReAttach(virNodeDevicePtr dev) +{ + VIR_DEBUG("dev=%p, conn=%p", dev, dev ? dev->conn : NULL); + + virResetLastError(); + + virCheckNodeDeviceReturn(dev, -1); + virCheckReadOnlyGoto(dev->conn->flags, error); + + if (dev->conn->driver->nodeDeviceReAttach) { + int ret; + ret = dev->conn->driver->nodeDeviceReAttach(dev); + if (ret < 0) + goto error; + return ret; + } + + virReportUnsupportedError(); + + error: + virDispatchError(dev->conn); + return -1; +} + + +/** + * virNodeDeviceReset: + * @dev: pointer to the node device + * + * Reset a previously dettached node device to the node before or + * after assigning it to a guest. + * + * The exact reset semantics depends on the hypervisor and device + * type but, for example, KVM will attempt to reset PCI devices with + * a Function Level Reset, Secondary Bus Reset or a Power Management + * D-State reset. + * + * If the reset will affect other devices which are currently in use, + * this function may fail. + * + * Returns 0 in case of success, -1 in case of failure. + */ +int +virNodeDeviceReset(virNodeDevicePtr dev) +{ + VIR_DEBUG("dev=%p, conn=%p", dev, dev ? dev->conn : NULL); + + virResetLastError(); + + virCheckNodeDeviceReturn(dev, -1); + virCheckReadOnlyGoto(dev->conn->flags, error); + + if (dev->conn->driver->nodeDeviceReset) { + int ret; + ret = dev->conn->driver->nodeDeviceReset(dev); + if (ret < 0) + goto error; + return ret; + } + + virReportUnsupportedError(); + + error: + virDispatchError(dev->conn); + return -1; +} + + +/** + * virNodeDeviceCreateXML: + * @conn: pointer to the hypervisor connection + * @xmlDesc: string containing an XML description of the device to be created + * @flags: extra flags; not used yet, so callers should always pass 0 + * + * Create a new device on the VM host machine, for example, virtual + * HBAs created using vport_create. + * + * virNodeDeviceFree should be used to free the resources after the + * node device object is no longer needed. + * + * Returns a node device object if successful, NULL in case of failure + */ +virNodeDevicePtr +virNodeDeviceCreateXML(virConnectPtr conn, + const char *xmlDesc, + unsigned int flags) +{ + VIR_DEBUG("conn=%p, xmlDesc=%s, flags=%x", conn, xmlDesc, flags); + + virResetLastError(); + + virCheckConnectReturn(conn, NULL); + virCheckReadOnlyGoto(conn->flags, error); + virCheckNonNullArgGoto(xmlDesc, error); + + if (conn->nodeDeviceDriver && + conn->nodeDeviceDriver->nodeDeviceCreateXML) { + virNodeDevicePtr dev = conn->nodeDeviceDriver->nodeDeviceCreateXML(conn, xmlDesc, flags); + if (dev == NULL) + goto error; + return dev; + } + + virReportUnsupportedError(); + + error: + virDispatchError(conn); + return NULL; +} + + +/** + * virNodeDeviceDestroy: + * @dev: a device object + * + * Destroy the device object. The virtual device (only works for vHBA + * currently) is removed from the host operating system. This function + * may require privileged access. + * + * Returns 0 in case of success and -1 in case of failure. + */ +int +virNodeDeviceDestroy(virNodeDevicePtr dev) +{ + VIR_DEBUG("dev=%p", dev); + + virResetLastError(); + + virCheckNodeDeviceReturn(dev, -1); + virCheckReadOnlyGoto(dev->conn->flags, error); + + if (dev->conn->nodeDeviceDriver && + dev->conn->nodeDeviceDriver->nodeDeviceDestroy) { + int retval = dev->conn->nodeDeviceDriver->nodeDeviceDestroy(dev); + if (retval < 0) { + goto error; + } + + return 0; + } + + virReportUnsupportedError(); + + error: + virDispatchError(dev->conn); + return -1; +} diff --git a/src/libvirt.c b/src/libvirt.c index ad445a0..79f9696 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -12708,734 +12708,6 @@ virStorageVolResize(virStorageVolPtr vol, } -/** - * virNodeNumOfDevices: - * @conn: pointer to the hypervisor connection - * @cap: capability name - * @flags: extra flags; not used yet, so callers should always pass 0 - * - * Provides the number of node devices. - * - * If the optional 'cap' argument is non-NULL, then the count - * will be restricted to devices with the specified capability - * - * Returns the number of node devices or -1 in case of error - */ -int -virNodeNumOfDevices(virConnectPtr conn, const char *cap, unsigned int flags) -{ - VIR_DEBUG("conn=%p, cap=%s, flags=%x", conn, NULLSTR(cap), flags); - - virResetLastError(); - - virCheckConnectReturn(conn, -1); - - if (conn->nodeDeviceDriver && conn->nodeDeviceDriver->nodeNumOfDevices) { - int ret; - ret = conn->nodeDeviceDriver->nodeNumOfDevices(conn, cap, flags); - if (ret < 0) - goto error; - return ret; - } - - virReportUnsupportedError(); - - error: - virDispatchError(conn); - return -1; -} - - -/** - * virConnectListAllNodeDevices: - * @conn: Pointer to the hypervisor connection. - * @devices: Pointer to a variable to store the array containing the node - * device objects or NULL if the list is not required (just returns - * number of node devices). - * @flags: bitwise-OR of virConnectListAllNodeDevices. - * - * Collect the list of node devices, and allocate an array to store those - * objects. - * - * Normally, all node devices are returned; however, @flags can be used to - * filter the results for a smaller list of targeted node devices. The valid - * flags are divided into groups, where each group contains bits that - * describe mutually exclusive attributes of a node device, and where all bits - * within a group describe all possible node devices. - * - * Only one group of the @flags is provided to filter the node devices by - * capability type, flags include: - * VIR_CONNECT_LIST_NODE_DEVICES_CAP_SYSTEM - * VIR_CONNECT_LIST_NODE_DEVICES_CAP_PCI_DEV - * VIR_CONNECT_LIST_NODE_DEVICES_CAP_USB_DEV - * VIR_CONNECT_LIST_NODE_DEVICES_CAP_USB_INTERFACE - * VIR_CONNECT_LIST_NODE_DEVICES_CAP_NET - * VIR_CONNECT_LIST_NODE_DEVICES_CAP_SCSI_HOST - * VIR_CONNECT_LIST_NODE_DEVICES_CAP_SCSI_TARGET - * VIR_CONNECT_LIST_NODE_DEVICES_CAP_SCSI - * VIR_CONNECT_LIST_NODE_DEVICES_CAP_STORAGE - * VIR_CONNECT_LIST_NODE_DEVICES_CAP_FC_HOST - * VIR_CONNECT_LIST_NODE_DEVICES_CAP_VPORTS - * VIR_CONNECT_LIST_NODE_DEVICES_CAP_SCSI_GENERIC - * - * Returns the number of node devices found or -1 and sets @devices to NULL in - * case of error. On success, the array stored into @devices is guaranteed to - * have an extra allocated element set to NULL but not included in the return - * count, to make iteration easier. The caller is responsible for calling - * virNodeDeviceFree() on each array element, then calling free() on - * @devices. - */ -int -virConnectListAllNodeDevices(virConnectPtr conn, - virNodeDevicePtr **devices, - unsigned int flags) -{ - VIR_DEBUG("conn=%p, devices=%p, flags=%x", conn, devices, flags); - - virResetLastError(); - - if (devices) - *devices = NULL; - - virCheckConnectReturn(conn, -1); - - if (conn->nodeDeviceDriver && - conn->nodeDeviceDriver->connectListAllNodeDevices) { - int ret; - ret = conn->nodeDeviceDriver->connectListAllNodeDevices(conn, devices, flags); - if (ret < 0) - goto error; - return ret; - } - - virReportUnsupportedError(); - - error: - virDispatchError(conn); - return -1; -} - - -/** - * virNodeListDevices: - * @conn: pointer to the hypervisor connection - * @cap: capability name - * @names: array to collect the list of node device names - * @maxnames: size of @names - * @flags: extra flags; not used yet, so callers should always pass 0 - * - * Collect the list of node devices, and store their names in @names - * - * For more control over the results, see virConnectListAllNodeDevices(). - * - * If the optional 'cap' argument is non-NULL, then the count - * will be restricted to devices with the specified capability - * - * Returns the number of node devices found or -1 in case of error - */ -int -virNodeListDevices(virConnectPtr conn, - const char *cap, - char **const names, int maxnames, - unsigned int flags) -{ - VIR_DEBUG("conn=%p, cap=%s, names=%p, maxnames=%d, flags=%x", - conn, cap, names, maxnames, flags); - - virResetLastError(); - - virCheckConnectReturn(conn, -1); - virCheckNonNullArgGoto(names, error); - virCheckNonNegativeArgGoto(maxnames, error); - - if (conn->nodeDeviceDriver && conn->nodeDeviceDriver->nodeListDevices) { - int ret; - ret = conn->nodeDeviceDriver->nodeListDevices(conn, cap, names, maxnames, flags); - if (ret < 0) - goto error; - return ret; - } - - virReportUnsupportedError(); - - error: - virDispatchError(conn); - return -1; -} - - -/** - * virNodeDeviceLookupByName: - * @conn: pointer to the hypervisor connection - * @name: unique device name - * - * Lookup a node device by its name. - * - * virNodeDeviceFree should be used to free the resources after the - * node device object is no longer needed. - * - * Returns a virNodeDevicePtr if found, NULL otherwise. - */ -virNodeDevicePtr -virNodeDeviceLookupByName(virConnectPtr conn, const char *name) -{ - VIR_DEBUG("conn=%p, name=%p", conn, name); - - virResetLastError(); - - virCheckConnectReturn(conn, NULL); - virCheckNonNullArgGoto(name, error); - - if (conn->nodeDeviceDriver && conn->nodeDeviceDriver->nodeDeviceLookupByName) { - virNodeDevicePtr ret; - ret = conn->nodeDeviceDriver->nodeDeviceLookupByName(conn, name); - if (!ret) - goto error; - return ret; - } - - virReportUnsupportedError(); - - error: - virDispatchError(conn); - return NULL; -} - - -/** - * virNodeDeviceLookupSCSIHostByWWN: - * @conn: pointer to the hypervisor connection - * @wwnn: WWNN of the SCSI Host. - * @wwpn: WWPN of the SCSI Host. - * @flags: extra flags; not used yet, so callers should always pass 0 - * - * Lookup SCSI Host which is capable with 'fc_host' by its WWNN and WWPN. - * - * virNodeDeviceFree should be used to free the resources after the - * node device object is no longer needed. - * - * Returns a virNodeDevicePtr if found, NULL otherwise. - */ -virNodeDevicePtr -virNodeDeviceLookupSCSIHostByWWN(virConnectPtr conn, - const char *wwnn, - const char *wwpn, - unsigned int flags) -{ - VIR_DEBUG("conn=%p, wwnn=%p, wwpn=%p, flags=%x", conn, wwnn, wwpn, flags); - - virResetLastError(); - - virCheckConnectReturn(conn, NULL); - virCheckNonNullArgGoto(wwnn, error); - virCheckNonNullArgGoto(wwpn, error); - - if (conn->nodeDeviceDriver && - conn->nodeDeviceDriver->nodeDeviceLookupSCSIHostByWWN) { - virNodeDevicePtr ret; - ret = conn->nodeDeviceDriver->nodeDeviceLookupSCSIHostByWWN(conn, wwnn, - wwpn, flags); - if (!ret) - goto error; - return ret; - } - - virReportUnsupportedError(); - - error: - virDispatchError(conn); - return NULL; -} - - -/** - * virNodeDeviceGetXMLDesc: - * @dev: pointer to the node device - * @flags: extra flags; not used yet, so callers should always pass 0 - * - * Fetch an XML document describing all aspects of - * the device. - * - * Returns the XML document, or NULL on error - */ -char * -virNodeDeviceGetXMLDesc(virNodeDevicePtr dev, unsigned int flags) -{ - VIR_DEBUG("dev=%p, conn=%p, flags=%x", dev, dev ? dev->conn : NULL, flags); - - virResetLastError(); - - virCheckNodeDeviceReturn(dev, NULL); - - if (dev->conn->nodeDeviceDriver && dev->conn->nodeDeviceDriver->nodeDeviceGetXMLDesc) { - char *ret; - ret = dev->conn->nodeDeviceDriver->nodeDeviceGetXMLDesc(dev, flags); - if (!ret) - goto error; - return ret; - } - - virReportUnsupportedError(); - - error: - virDispatchError(dev->conn); - return NULL; -} - - -/** - * virNodeDeviceGetName: - * @dev: the device - * - * Just return the device name - * - * Returns the device name or NULL in case of error - */ -const char * -virNodeDeviceGetName(virNodeDevicePtr dev) -{ - VIR_DEBUG("dev=%p, conn=%p", dev, dev ? dev->conn : NULL); - - virResetLastError(); - - virCheckNodeDeviceReturn(dev, NULL); - - return dev->name; -} - - -/** - * virNodeDeviceGetParent: - * @dev: the device - * - * Accessor for the parent of the device - * - * Returns the name of the device's parent, or NULL if an - * error occurred or when the device has no parent. - */ -const char * -virNodeDeviceGetParent(virNodeDevicePtr dev) -{ - VIR_DEBUG("dev=%p, conn=%p", dev, dev ? dev->conn : NULL); - - virResetLastError(); - - virCheckNodeDeviceReturn(dev, NULL); - - if (!dev->parent) { - if (dev->conn->nodeDeviceDriver && dev->conn->nodeDeviceDriver->nodeDeviceGetParent) { - dev->parent = dev->conn->nodeDeviceDriver->nodeDeviceGetParent(dev); - } else { - virReportUnsupportedError(); - virDispatchError(dev->conn); - return NULL; - } - } - return dev->parent; -} - - -/** - * virNodeDeviceNumOfCaps: - * @dev: the device - * - * Accessor for the number of capabilities supported by the device. - * - * Returns the number of capabilities supported by the device or -1 - * in case of error. - */ -int -virNodeDeviceNumOfCaps(virNodeDevicePtr dev) -{ - VIR_DEBUG("dev=%p, conn=%p", dev, dev ? dev->conn : NULL); - - virResetLastError(); - - virCheckNodeDeviceReturn(dev, -1); - - if (dev->conn->nodeDeviceDriver && dev->conn->nodeDeviceDriver->nodeDeviceNumOfCaps) { - int ret; - ret = dev->conn->nodeDeviceDriver->nodeDeviceNumOfCaps(dev); - if (ret < 0) - goto error; - return ret; - } - - virReportUnsupportedError(); - - error: - virDispatchError(dev->conn); - return -1; -} - - -/** - * virNodeDeviceListCaps: - * @dev: the device - * @names: array to collect the list of capability names - * @maxnames: size of @names - * - * Lists the names of the capabilities supported by the device. - * - * Returns the number of capability names listed in @names or -1 - * in case of error. - */ -int -virNodeDeviceListCaps(virNodeDevicePtr dev, - char **const names, - int maxnames) -{ - VIR_DEBUG("dev=%p, conn=%p, names=%p, maxnames=%d", - dev, dev ? dev->conn : NULL, names, maxnames); - - virResetLastError(); - - virCheckNodeDeviceReturn(dev, -1); - virCheckNonNullArgGoto(names, error); - virCheckNonNegativeArgGoto(maxnames, error); - - if (dev->conn->nodeDeviceDriver && dev->conn->nodeDeviceDriver->nodeDeviceListCaps) { - int ret; - ret = dev->conn->nodeDeviceDriver->nodeDeviceListCaps(dev, names, maxnames); - if (ret < 0) - goto error; - return ret; - } - - virReportUnsupportedError(); - - error: - virDispatchError(dev->conn); - return -1; -} - - -/** - * virNodeDeviceFree: - * @dev: pointer to the node device - * - * Drops a reference to the node device, freeing it if - * this was the last reference. - * - * Returns the 0 for success, -1 for error. - */ -int -virNodeDeviceFree(virNodeDevicePtr dev) -{ - VIR_DEBUG("dev=%p, conn=%p", dev, dev ? dev->conn : NULL); - - virResetLastError(); - - virCheckNodeDeviceReturn(dev, -1); - - virObjectUnref(dev); - return 0; -} - - -/** - * virNodeDeviceRef: - * @dev: the dev to hold a reference on - * - * Increment the reference count on the dev. For each - * additional call to this method, there shall be a corresponding - * call to virNodeDeviceFree to release the reference count, once - * the caller no longer needs the reference to this object. - * - * This method is typically useful for applications where multiple - * threads are using a connection, and it is required that the - * connection remain open until all threads have finished using - * it. ie, each new thread using a dev would increment - * the reference count. - * - * Returns 0 in case of success, -1 in case of failure. - */ -int -virNodeDeviceRef(virNodeDevicePtr dev) -{ - VIR_DEBUG("dev=%p refs=%d", dev, dev ? dev->object.u.s.refs : 0); - - virResetLastError(); - - virCheckNodeDeviceReturn(dev, -1); - - virObjectRef(dev); - return 0; -} - - -/** - * virNodeDeviceDettach: - * @dev: pointer to the node device - * - * Dettach the node device from the node itself so that it may be - * assigned to a guest domain. - * - * Depending on the hypervisor, this may involve operations such - * as unbinding any device drivers from the device, binding the - * device to a dummy device driver and resetting the device. - * - * If the device is currently in use by the node, this method may - * fail. - * - * Once the device is not assigned to any guest, it may be re-attached - * to the node using the virNodeDeviceReattach() method. - * - * If the caller needs control over which backend driver will be used - * during PCI device assignment (to use something other than the - * default, for example VFIO), the newer virNodeDeviceDetachFlags() - * API should be used instead. - * - * Returns 0 in case of success, -1 in case of failure. - */ -int -virNodeDeviceDettach(virNodeDevicePtr dev) -{ - VIR_DEBUG("dev=%p, conn=%p", dev, dev ? dev->conn : NULL); - - virResetLastError(); - - virCheckNodeDeviceReturn(dev, -1); - virCheckReadOnlyGoto(dev->conn->flags, error); - - if (dev->conn->driver->nodeDeviceDettach) { - int ret; - ret = dev->conn->driver->nodeDeviceDettach(dev); - if (ret < 0) - goto error; - return ret; - } - - virReportUnsupportedError(); - - error: - virDispatchError(dev->conn); - return -1; -} - - -/** - * virNodeDeviceDetachFlags: - * @dev: pointer to the node device - * @driverName: name of backend driver that will be used - * for later device assignment to a domain. NULL - * means "use the hypervisor default driver" - * @flags: extra flags; not used yet, so callers should always pass 0 - * - * Detach the node device from the node itself so that it may be - * assigned to a guest domain. - * - * Depending on the hypervisor, this may involve operations such as - * unbinding any device drivers from the device, binding the device to - * a dummy device driver and resetting the device. Different backend - * drivers expect the device to be bound to different dummy - * devices. For example, QEMU's "kvm" backend driver (the default) - * expects the device to be bound to "pci-stub", but its "vfio" - * backend driver expects the device to be bound to "vfio-pci". - * - * If the device is currently in use by the node, this method may - * fail. - * - * Once the device is not assigned to any guest, it may be re-attached - * to the node using the virNodeDeviceReAttach() method. - * - * Returns 0 in case of success, -1 in case of failure. - */ -int -virNodeDeviceDetachFlags(virNodeDevicePtr dev, - const char *driverName, - unsigned int flags) -{ - VIR_DEBUG("dev=%p, conn=%p driverName=%s flags=%x", - dev, dev ? dev->conn : NULL, - driverName ? driverName : "(default)", flags); - - virResetLastError(); - - virCheckNodeDeviceReturn(dev, -1); - virCheckReadOnlyGoto(dev->conn->flags, error); - - if (dev->conn->driver->nodeDeviceDetachFlags) { - int ret; - ret = dev->conn->driver->nodeDeviceDetachFlags(dev, driverName, flags); - if (ret < 0) - goto error; - return ret; - } - - virReportUnsupportedError(); - - error: - virDispatchError(dev->conn); - return -1; -} - - -/** - * virNodeDeviceReAttach: - * @dev: pointer to the node device - * - * Re-attach a previously dettached node device to the node so that it - * may be used by the node again. - * - * Depending on the hypervisor, this may involve operations such - * as resetting the device, unbinding it from a dummy device driver - * and binding it to its appropriate driver. - * - * If the device is currently in use by a guest, this method may fail. - * - * Returns 0 in case of success, -1 in case of failure. - */ -int -virNodeDeviceReAttach(virNodeDevicePtr dev) -{ - VIR_DEBUG("dev=%p, conn=%p", dev, dev ? dev->conn : NULL); - - virResetLastError(); - - virCheckNodeDeviceReturn(dev, -1); - virCheckReadOnlyGoto(dev->conn->flags, error); - - if (dev->conn->driver->nodeDeviceReAttach) { - int ret; - ret = dev->conn->driver->nodeDeviceReAttach(dev); - if (ret < 0) - goto error; - return ret; - } - - virReportUnsupportedError(); - - error: - virDispatchError(dev->conn); - return -1; -} - - -/** - * virNodeDeviceReset: - * @dev: pointer to the node device - * - * Reset a previously dettached node device to the node before or - * after assigning it to a guest. - * - * The exact reset semantics depends on the hypervisor and device - * type but, for example, KVM will attempt to reset PCI devices with - * a Function Level Reset, Secondary Bus Reset or a Power Management - * D-State reset. - * - * If the reset will affect other devices which are currently in use, - * this function may fail. - * - * Returns 0 in case of success, -1 in case of failure. - */ -int -virNodeDeviceReset(virNodeDevicePtr dev) -{ - VIR_DEBUG("dev=%p, conn=%p", dev, dev ? dev->conn : NULL); - - virResetLastError(); - - virCheckNodeDeviceReturn(dev, -1); - virCheckReadOnlyGoto(dev->conn->flags, error); - - if (dev->conn->driver->nodeDeviceReset) { - int ret; - ret = dev->conn->driver->nodeDeviceReset(dev); - if (ret < 0) - goto error; - return ret; - } - - virReportUnsupportedError(); - - error: - virDispatchError(dev->conn); - return -1; -} - - -/** - * virNodeDeviceCreateXML: - * @conn: pointer to the hypervisor connection - * @xmlDesc: string containing an XML description of the device to be created - * @flags: extra flags; not used yet, so callers should always pass 0 - * - * Create a new device on the VM host machine, for example, virtual - * HBAs created using vport_create. - * - * virNodeDeviceFree should be used to free the resources after the - * node device object is no longer needed. - * - * Returns a node device object if successful, NULL in case of failure - */ -virNodeDevicePtr -virNodeDeviceCreateXML(virConnectPtr conn, - const char *xmlDesc, - unsigned int flags) -{ - VIR_DEBUG("conn=%p, xmlDesc=%s, flags=%x", conn, xmlDesc, flags); - - virResetLastError(); - - virCheckConnectReturn(conn, NULL); - virCheckReadOnlyGoto(conn->flags, error); - virCheckNonNullArgGoto(xmlDesc, error); - - if (conn->nodeDeviceDriver && - conn->nodeDeviceDriver->nodeDeviceCreateXML) { - virNodeDevicePtr dev = conn->nodeDeviceDriver->nodeDeviceCreateXML(conn, xmlDesc, flags); - if (dev == NULL) - goto error; - return dev; - } - - virReportUnsupportedError(); - - error: - virDispatchError(conn); - return NULL; -} - - -/** - * virNodeDeviceDestroy: - * @dev: a device object - * - * Destroy the device object. The virtual device (only works for vHBA - * currently) is removed from the host operating system. This function - * may require privileged access. - * - * Returns 0 in case of success and -1 in case of failure. - */ -int -virNodeDeviceDestroy(virNodeDevicePtr dev) -{ - VIR_DEBUG("dev=%p", dev); - - virResetLastError(); - - virCheckNodeDeviceReturn(dev, -1); - virCheckReadOnlyGoto(dev->conn->flags, error); - - if (dev->conn->nodeDeviceDriver && - dev->conn->nodeDeviceDriver->nodeDeviceDestroy) { - int retval = dev->conn->nodeDeviceDriver->nodeDeviceDestroy(dev); - if (retval < 0) { - goto error; - } - - return 0; - } - - virReportUnsupportedError(); - - error: - virDispatchError(dev->conn); - return -1; -} - - /* * Domain Event Notification */ -- 2.1.0 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list