Re: [libvirt] Re: [PATCH 2/6] host (node) device enumeration - internal API additions

2008-10-28 Thread Daniel Veillard
On Tue, Oct 21, 2008 at 01:54:13PM -0400, David Lively wrote:
 This patch contains the internal API additions.

  Looks fine to me, just a couple of questions:

 +// TODO: Implement PCI bus devs
 +// TODO: Implement USB bus devs

  Any reason it's not in ? I would expect HAL to report them, no ?

 +
 +// TODO: virNodeDeviceDefParseString/File/Node for virNodeDeviceCreate

  No sure, could you explain a bit ?

thanks,

Daniel

-- 
Daniel Veillard  | libxml Gnome XML XSLT toolkit  http://xmlsoft.org/
[EMAIL PROTECTED]  | Rpmfind RPM search engine http://rpmfind.net/
http://veillard.com/ | virtualization library  http://libvirt.org/

--
Libvir-list mailing list
Libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] Re: [PATCH 2/6] host (node) device enumeration - internal API additions

2008-10-28 Thread Daniel Veillard
On Tue, Oct 28, 2008 at 11:32:03AM -0400, David Lively wrote:
 On Tue, 2008-10-28 at 14:13 +0100, Daniel Veillard wrote:
  On Tue, Oct 21, 2008 at 01:54:13PM -0400, David Lively wrote:
   This patch contains the internal API additions.
  
Looks fine to me, just a couple of questions:
  
   +// TODO: Implement PCI bus devs
   +// TODO: Implement USB bus devs
  
Any reason it's not in ? I would expect HAL to report them, no ?
 
 I posted a new patch set yesterday that (among other things) removed the
 PCI_BUS and USB_BUS devices.  Currently HAL doesn't report them as
 anything special, e.g.:
 
 udi = '/org/freedesktop/Hal/devices/pci_8086_27cc'
   info.linux.driver = 'ehci_hcd'  (string)
   info.parent = '/org/freedesktop/Hal/devices/computer'  (string)
   info.product = '82801G (ICH7 Family) USB2 EHCI Controller'  (string)
   info.subsystem = 'pci'  (string)
   info.udi = '/org/freedesktop/Hal/devices/pci_8086_27cc'  (string)
   info.vendor = 'Intel Corporation'  (string)
   linux.hotplug_type = 2  (0x2)  (int)
   linux.subsystem = 'pci'  (string)
   linux.sysfs_path = '/sys/devices/pci:00/:00:1d.7'  (string)
   pci.device_class = 12  (0xc)  (int)
   pci.device_protocol = 32  (0x20)  (int)
   pci.device_subclass = 3  (0x3)  (int)
   pci.linux.sysfs_path = '/sys/devices/pci:00/:00:1d.7'
 (string)
   pci.product = '82801G (ICH7 Family) USB2 EHCI Controller'  (string)
   pci.product_id = 10188  (0x27cc)  (int)
   pci.subsys_product_id = 22594  (0x5842)  (int)
   pci.subsys_vendor = 'Intel Corporation'  (string)
   pci.subsys_vendor_id = 32902  (0x8086)  (int)
   pci.vendor = 'Intel Corporation'  (string)
   pci.vendor_id = 32902  (0x8086)  (int)
 
 udi = '/org/freedesktop/Hal/devices/pci_8086_244e'
   info.parent = '/org/freedesktop/Hal/devices/computer'  (string)
   info.product = '82801 PCI Bridge'  (string)
   info.subsystem = 'pci'  (string)
   info.udi = '/org/freedesktop/Hal/devices/pci_8086_244e'  (string)
   info.vendor = 'Intel Corporation'  (string)
   linux.hotplug_type = 2  (0x2)  (int)
   linux.subsystem = 'pci'  (string)
   linux.sysfs_path = '/sys/devices/pci:00/:00:1e.0'  (string)
   pci.device_class = 6  (0x6)  (int)
   pci.device_protocol = 1  (0x1)  (int)
   pci.device_subclass = 4  (0x4)  (int)
   pci.linux.sysfs_path = '/sys/devices/pci:00/:00:1e.0'
 (string)
   pci.product = '82801 PCI Bridge'  (string)
   pci.product_id = 9294  (0x244e)  (int)
   pci.subsys_product_id = 0  (0x0)  (int)
   pci.subsys_vendor_id = 0  (0x0)  (int)
   pci.vendor = 'Intel Corporation'  (string)
   pci.vendor_id = 32902  (0x8086)  (int)
 
 So at this point, I just report them as PCI devices, though of course
 the PCI bridge will be the parent of PCI devices on that bus, and the
 USB controller will be the parent of USB devices controlled by it.  Any
 client code that needs to recognize them specifically as PCI or USB bus
 controllers can use the PCI device attributes for that.
 
 Hmmm ... currently I expose the product  vendor info for PCI devices,
 along with their bus addressing info.  But perhaps I should also expose
 their device_class, protocol, and subclass??
 
   +
   +// TODO: virNodeDeviceDefParseString/File/Node for virNodeDeviceCreate
 
 Currently I have no need to parse a NodeDevice definition.  But
 virNodeDeviceCreate will need to do that, once it's implemented.  (I
 don't have any NPIV NICs or other such toys to play with right now.
 Daniel B says he'll implement Create/Destroy since he does.)  I also
 thought it would be better to postpone the parser work until needed
 since the node definition seems likely to change as we work out the
 details here.

  Okay, thanks for the clarification, and sorry for the delay,
as you can guess I didn't yet reached the end of the folder grin/ !

Daniel

-- 
Daniel Veillard  | libxml Gnome XML XSLT toolkit  http://xmlsoft.org/
[EMAIL PROTECTED]  | Rpmfind RPM search engine http://rpmfind.net/
http://veillard.com/ | virtualization library  http://libvirt.org/

--
Libvir-list mailing list
Libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] Re: [PATCH 2/6] host (node) device enumeration - internal API additions

2008-10-21 Thread David Lively
This patch contains the internal API additions.

diff --git a/src/hash.c b/src/hash.c
index 0a5bdcd..424c4a7 100644
--- a/src/hash.c
+++ b/src/hash.c
@@ -687,6 +687,9 @@ virGetConnect(void) {
 ret-storageVols = virHashCreate(20);
 if (ret-storageVols == NULL)
 goto failed;
+ret-nodeDevices = virHashCreate(256);
+if (ret-nodeDevices == NULL)
+goto failed;
 
 pthread_mutex_init(ret-lock, NULL);
 
@@ -703,6 +706,8 @@ failed:
 virHashFree(ret-storagePools, (virHashDeallocator) virStoragePoolFreeName);
 if (ret-storageVols != NULL)
 virHashFree(ret-storageVols, (virHashDeallocator) virStorageVolFreeName);
+if (ret-nodeDevices != NULL)
+virHashFree(ret-nodeDevices, (virHashDeallocator) virNodeDeviceFree);
 
 pthread_mutex_destroy(ret-lock);
 VIR_FREE(ret);
@@ -730,6 +735,8 @@ virReleaseConnect(virConnectPtr conn) {
 virHashFree(conn-storagePools, (virHashDeallocator) virStoragePoolFreeName);
 if (conn-storageVols != NULL)
 virHashFree(conn-storageVols, (virHashDeallocator) virStorageVolFreeName);
+if (conn-nodeDevices != NULL)
+virHashFree(conn-nodeDevices, (virHashDeallocator) virNodeDeviceFree);
 
 virResetError(conn-err);
 if (__lastErr.conn == conn)
@@ -1318,3 +1325,126 @@ virUnrefStorageVol(virStorageVolPtr vol) {
 pthread_mutex_unlock(vol-conn-lock);
 return (refs);
 }
+
+
+/**
+ * virGetNodeDevice:
+ * @conn: the hypervisor connection
+ * @name: device name (unique on node)
+ *
+ * Lookup if the device is already registered for that connection,
+ * if yes return a new pointer to it, if no allocate a new structure,
+ * and register it in the table. In any case a corresponding call to
+ * virFreeNodeDevice() is needed to not leak data.
+ *
+ * Returns a pointer to the node device, or NULL in case of failure
+ */
+virNodeDevicePtr
+__virGetNodeDevice(virConnectPtr conn, const char *name)
+{
+virNodeDevicePtr ret = NULL;
+
+if ((!VIR_IS_CONNECT(conn)) || (name == NULL)) {
+virHashError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+return(NULL);
+}
+pthread_mutex_lock(conn-lock);
+
+ret = (virNodeDevicePtr) virHashLookup(conn-nodeDevices, name);
+if (ret == NULL) {
+   if (VIR_ALLOC(ret)  0) {
+virHashError(conn, VIR_ERR_NO_MEMORY, _(allocating node dev));
+goto error;
+}
+ret-magic = VIR_NODE_DEVICE_MAGIC;
+ret-conn = conn;
+ret-name = strdup(name);
+if (ret-name == NULL) {
+virHashError(conn, VIR_ERR_NO_MEMORY, _(copying node dev name));
+goto error;
+}
+
+if (virHashAddEntry(conn-nodeDevices, name, ret)  0) {
+virHashError(conn, VIR_ERR_INTERNAL_ERROR,
+ _(failed to add node dev to conn hash table));
+goto error;
+}
+conn-refs++;
+}
+ret-refs++;
+pthread_mutex_unlock(conn-lock);
+return(ret);
+
+error:
+pthread_mutex_unlock(conn-lock);
+if (ret != NULL) {
+VIR_FREE(ret-name);
+VIR_FREE(ret);
+}
+return(NULL);
+}
+
+
+/**
+ * virReleaseNodeDevice:
+ * @dev: the dev to release
+ *
+ * Unconditionally release all memory associated with a dev.
+ * The conn.lock mutex must be held prior to calling this, and will
+ * be released prior to this returning. The dev obj must not
+ * be used once this method returns.
+ *
+ * It will also unreference the associated connection object,
+ * which may also be released if its ref count hits zero.
+ */
+static void
+virReleaseNodeDevice(virNodeDevicePtr dev) {
+virConnectPtr conn = dev-conn;
+DEBUG(release dev %p %s, dev, dev-name);
+
+if (virHashRemoveEntry(conn-nodeDevices, dev-name, NULL)  0)
+virHashError(conn, VIR_ERR_INTERNAL_ERROR,
+ _(dev missing from connection hash table));
+
+dev-magic = -1;
+VIR_FREE(dev-name);
+VIR_FREE(dev);
+
+DEBUG(unref connection %p %s %d, conn, conn-name, conn-refs);
+conn-refs--;
+if (conn-refs == 0) {
+virReleaseConnect(conn);
+/* Already unlocked mutex */
+return;
+}
+
+pthread_mutex_unlock(conn-lock);
+}
+
+
+/**
+ * virUnrefNodeDevice:
+ * @dev: the dev to unreference
+ *
+ * Unreference the dev. If the use count drops to zero, the structure is
+ * actually freed.
+ *
+ * Returns the reference count or -1 in case of failure.
+ */
+int
+virUnrefNodeDevice(virNodeDevicePtr dev) {
+int refs;
+
+pthread_mutex_lock(dev-conn-lock);
+DEBUG(unref dev %p %s %d, dev, dev-name, dev-refs);
+dev-refs--;
+refs = dev-refs;
+if (refs == 0) {
+virReleaseNodeDevice(dev);
+/* Already unlocked mutex */
+return (0);
+}
+
+pthread_mutex_unlock(dev-conn-lock);
+return (refs);
+}
diff --git a/src/internal.h b/src/internal.h
index 2ae764d..76b57ad 100644
--- a/src/internal.h
+++ b/src/internal.h
@@ -37,6