diff --git a/ChangeLog b/ChangeLog index 2dfcb141272a361472352d86caf7227ee91ecdff..1d82eac76cad360e549f5ccc3055510c751fe98f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +Mon Mar 2 17:19:23 CET 2009 Daniel Veillard + + * include/libvirt/libvirt.h include/libvirt/libvirt.h.in + src/driver.h src/libvirt.c src/libvirt_public.syms + src/lxc_driver.c src/openvz_driver.c src/qemu_driver.c + src/test.c src/uml_driver.c: add the public APIs for + virNodeDeviceDettach virNodeDeviceReAttach and virNodeDeviceReset + and extends the driver structure accordingly. + Mon Mar 2 17:07:44 CET 2009 Daniel Veillard * configure.in po/POTFILES.in src/Makefile.am src/libvirt_private.syms diff --git a/include/libvirt/libvirt.h b/include/libvirt/libvirt.h index e32d40b7fa1699479176c8b8ceaeb52d9d930d50..cf39488bd940fb0354bcf2f9357420ceb0219e29 100644 --- a/include/libvirt/libvirt.h +++ b/include/libvirt/libvirt.h @@ -1053,6 +1053,10 @@ char * virNodeDeviceGetXMLDesc (virNodeDevicePtr dev, int virNodeDeviceRef (virNodeDevicePtr dev); int virNodeDeviceFree (virNodeDevicePtr dev); +int virNodeDeviceDettach (virNodeDevicePtr dev); +int virNodeDeviceReAttach (virNodeDevicePtr dev); +int virNodeDeviceReset (virNodeDevicePtr dev); + /* * Domain Event Notification */ diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index af97bfd35ee0012e6b675f7ec3fff66303ac3e66..06361de0f97c0be96df693d620f300296b4fd8a4 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -1053,6 +1053,10 @@ char * virNodeDeviceGetXMLDesc (virNodeDevicePtr dev, int virNodeDeviceRef (virNodeDevicePtr dev); int virNodeDeviceFree (virNodeDevicePtr dev); +int virNodeDeviceDettach (virNodeDevicePtr dev); +int virNodeDeviceReAttach (virNodeDevicePtr dev); +int virNodeDeviceReset (virNodeDevicePtr dev); + /* * Domain Event Notification */ diff --git a/src/driver.h b/src/driver.h index 32d425730ea7791eff22ec63788833828230edf8..ffb95dc8adc4513cbd4f7cbe9e0e18dab38565e3 100644 --- a/src/driver.h +++ b/src/driver.h @@ -313,6 +313,16 @@ typedef virDomainPtr unsigned long flags, int retcode); +typedef int + (*virDrvNodeDeviceDettach) + (virNodeDevicePtr dev); +typedef int + (*virDrvNodeDeviceReAttach) + (virNodeDevicePtr dev); +typedef int + (*virDrvNodeDeviceReset) + (virNodeDevicePtr dev); + /** * _virDriver: * @@ -387,6 +397,9 @@ struct _virDriver { virDrvDomainEventDeregister domainEventDeregister; virDrvDomainMigratePrepare2 domainMigratePrepare2; virDrvDomainMigrateFinish2 domainMigrateFinish2; + virDrvNodeDeviceDettach nodeDeviceDettach; + virDrvNodeDeviceReAttach nodeDeviceReAttach; + virDrvNodeDeviceReset nodeDeviceReset; }; typedef int diff --git a/src/libvirt.c b/src/libvirt.c index 038a1ac4cf7b525f36c58763a0b9a48e72268f12..bc444dd71e69b467fa1a9871b258a8a296edad1f 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -7286,6 +7286,135 @@ virNodeDeviceRef(virNodeDevicePtr dev) return 0; } +/** + * virNodeDeviceAttach: + * @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. + */ +int +virNodeDeviceDettach(virNodeDevicePtr dev) +{ + DEBUG("dev=%p, conn=%p", dev, dev ? dev->conn : NULL); + + virResetLastError(); + + if (!VIR_IS_CONNECTED_NODE_DEVICE(dev)) { + virLibNodeDeviceError(NULL, VIR_ERR_INVALID_NODE_DEVICE, __FUNCTION__); + return (-1); + } + + if (dev->conn->driver->nodeDeviceDettach) { + int ret; + ret = dev->conn->driver->nodeDeviceDettach (dev); + if (ret < 0) + goto error; + return ret; + } + + virLibConnError(dev->conn, VIR_ERR_NO_SUPPORT, __FUNCTION__); + +error: + /* Copy to connection error object for back compatability */ + virSetConnError(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. + */ +int +virNodeDeviceReAttach(virNodeDevicePtr dev) +{ + DEBUG("dev=%p, conn=%p", dev, dev ? dev->conn : NULL); + + virResetLastError(); + + if (!VIR_IS_CONNECTED_NODE_DEVICE(dev)) { + virLibNodeDeviceError(NULL, VIR_ERR_INVALID_NODE_DEVICE, __FUNCTION__); + return (-1); + } + + if (dev->conn->driver->nodeDeviceReAttach) { + int ret; + ret = dev->conn->driver->nodeDeviceReAttach (dev); + if (ret < 0) + goto error; + return ret; + } + + virLibConnError(dev->conn, VIR_ERR_NO_SUPPORT, __FUNCTION__); + +error: + /* Copy to connection error object for back compatability */ + virSetConnError(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. + */ +int +virNodeDeviceReset(virNodeDevicePtr dev) +{ + DEBUG("dev=%p, conn=%p", dev, dev ? dev->conn : NULL); + + virResetLastError(); + + if (!VIR_IS_CONNECTED_NODE_DEVICE(dev)) { + virLibNodeDeviceError(NULL, VIR_ERR_INVALID_NODE_DEVICE, __FUNCTION__); + return (-1); + } + + if (dev->conn->driver->nodeDeviceReset) { + int ret; + ret = dev->conn->driver->nodeDeviceReset (dev); + if (ret < 0) + goto error; + return ret; + } + + virLibConnError(dev->conn, VIR_ERR_NO_SUPPORT, __FUNCTION__); + +error: + /* Copy to connection error object for back compatability */ + virSetConnError(dev->conn); + return (-1); +} + /* * Domain Event Notification diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms index 1422e4cea8616eacd48ac4b2c65540cb5b319f6d..8114073d38be93a1da84869e29dea7ccc5e5574c 100644 --- a/src/libvirt_public.syms +++ b/src/libvirt_public.syms @@ -251,6 +251,9 @@ LIBVIRT_0.6.1 { global: virFreeError; virSaveLastError; + virNodeDeviceDettach; + virNodeDeviceReAttach; + virNodeDeviceReset; } LIBVIRT_0.6.0; # .... define new API here using predicted next version number .... diff --git a/src/lxc_driver.c b/src/lxc_driver.c index aa417a91fae8a0cd15a5254697358687701c3fea..28f2c6f9ee8564f5a4adc6ad28957586b9e490fd 100644 --- a/src/lxc_driver.c +++ b/src/lxc_driver.c @@ -1455,6 +1455,9 @@ static virDriver lxcDriver = { NULL, /* domainEventDeregister */ NULL, /* domainMigratePrepare2 */ NULL, /* domainMigrateFinish2 */ + NULL, /* nodeDeviceAttach */ + NULL, /* nodeDeviceReAttach */ + NULL, /* nodeDeviceReset */ }; static virStateDriver lxcStateDriver = { diff --git a/src/openvz_driver.c b/src/openvz_driver.c index e004819090b1b254157dafeb29dfff5ba9715b9e..b4d91286077e02af2e5437203168bd4f45193b93 100644 --- a/src/openvz_driver.c +++ b/src/openvz_driver.c @@ -1325,6 +1325,9 @@ static virDriver openvzDriver = { NULL, /* domainEventDeregister */ NULL, /* domainMigratePrepare2 */ NULL, /* domainMigrateFinish2 */ + NULL, /* nodeDeviceAttach */ + NULL, /* nodeDeviceReAttach */ + NULL, /* nodeDeviceReset */ }; int openvzRegister(void) { diff --git a/src/qemu_driver.c b/src/qemu_driver.c index 11782b458d8ca292111718f6f4d3a28fd00a15f2..8ba080585aa1801100eed79e8bf364caed5da75c 100644 --- a/src/qemu_driver.c +++ b/src/qemu_driver.c @@ -4572,6 +4572,9 @@ static virDriver qemuDriver = { qemudDomainEventDeregister, /* domainEventDeregister */ qemudDomainMigratePrepare2, /* domainMigratePrepare2 */ qemudDomainMigrateFinish2, /* domainMigrateFinish2 */ + NULL, /* nodeDeviceDettach */ + NULL, /* nodeDeviceReAttach */ + NULL, /* nodeDeviceReset */ }; diff --git a/src/test.c b/src/test.c index 226fe2e91583558a13e60e0b1950d779c32d8590..833faf07c58c95659f19934a0f68903f76a14655 100644 --- a/src/test.c +++ b/src/test.c @@ -3527,6 +3527,9 @@ static virDriver testDriver = { testDomainEventDeregister, /* domainEventDeregister */ NULL, /* domainMigratePrepare2 */ NULL, /* domainMigrateFinish2 */ + NULL, /* nodeDeviceAttach */ + NULL, /* nodeDeviceReAttach */ + NULL, /* nodeDeviceReset */ }; static virNetworkDriver testNetworkDriver = { diff --git a/src/uml_driver.c b/src/uml_driver.c index c5a06a21003146baf3327893c1def7502d5a9269..aec22ec2e8c062b609461bc37ff9ec7028743c67 100644 --- a/src/uml_driver.c +++ b/src/uml_driver.c @@ -1885,6 +1885,9 @@ static virDriver umlDriver = { NULL, /* domainEventUnregister */ NULL, /* domainMigratePrepare2 */ NULL, /* domainMigrateFinish2 */ + NULL, /* nodeDeviceAttach */ + NULL, /* nodeDeviceReAttach */ + NULL, /* nodeDeviceReset */ };