Re: [libvirt] mingw warnings

2008-10-27 Thread Richard W.M. Jones
On Fri, Oct 24, 2008 at 07:50:13PM +0200, Jim Meyering wrote:
 I've been building with mingw to make sure that my gnulib-upgrade-and-extend
 patch doesn't break anything and found some compiler warnings.
 I fixed most of them, but this one is ugly:
 
   ../qemud/remote_protocol.c:317: warning: assignment from incompatible 
 pointer type
   ../qemud/remote_protocol.c:346: warning: assignment from incompatible 
 pointer type
 
 That's due to the fact that the mingw xdr.h header,
 /usr/i686-pc-mingw32/sys-root/mingw/include/rpc/xdr.h, defines this
 
 #define   XDR_INLINE(xdrs, len)   \
   (*(xdrs)-x_ops-x_inline)(xdrs, len)
 
 and has an x_inline member of type long*,
 
 typedef struct {
   enum xdr_op x_op;   /* operation; fast additional param */
   struct xdr_ops {
   bool_t  (*x_getlong)(); /* get a long from underlying stream */
   bool_t  (*x_putlong)(); /* put a long to  */
   bool_t  (*x_getbytes)();/* get some bytes from  */
   bool_t  (*x_putbytes)();/* put some bytes to  */
   u_int   (*x_getpostn)();/* returns bytes off from beginning */
   bool_t  (*x_setpostn)();/* lets you reposition the stream */
   long *  (*x_inline)();  /* buf quick ptr to buffered data */
 
 while we're used to one with type matching buf: int32_t*:
 
 If you're serious about getting rid of warnings even on mingw,
 here's one approach:

I guess I'd agree with Dan that the best place to fix this is in
PortableXDR itself.

Converting that 'long *' - 'int32_t *' should be OK I think?  Unless
that x_inline member is used for other XDR types.

Rich.

PS. Windows is a strange platform in that when they moved to 64 bits,
they didn't go with LP64, but with LLP64.  So 'long' on Windows is
always 32 bits, even on Win64.  This is only a theoretical concern for
MinGW at the moment, but understanding it may help portability issues
in future.  In particular, all the places which use 'long' in the
libvirt public API are to be considered suspect.

-- 
Richard Jones, Emerging Technologies, Red Hat  http://et.redhat.com/~rjones
virt-p2v converts physical machines to virtual machines.  Boot with a
live CD or over the network (PXE) and turn machines into Xen guests.
http://et.redhat.com/~rjones/virt-p2v

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


Re: [libvirt] mingw warnings

2008-10-27 Thread Jim Meyering
Richard W.M. Jones [EMAIL PROTECTED] wrote:
 On Fri, Oct 24, 2008 at 07:50:13PM +0200, Jim Meyering wrote:
 I've been building with mingw to make sure that my gnulib-upgrade-and-extend
 patch doesn't break anything and found some compiler warnings.
 I fixed most of them, but this one is ugly:

   ../qemud/remote_protocol.c:317: warning: assignment from incompatible 
 pointer type
   ../qemud/remote_protocol.c:346: warning: assignment from incompatible 
 pointer type

 That's due to the fact that the mingw xdr.h header,
 /usr/i686-pc-mingw32/sys-root/mingw/include/rpc/xdr.h, defines this

 #define  XDR_INLINE(xdrs, len)   \
  (*(xdrs)-x_ops-x_inline)(xdrs, len)

 and has an x_inline member of type long*,

 typedef struct {
  enum xdr_op x_op;   /* operation; fast additional param */
  struct xdr_ops {
  bool_t  (*x_getlong)(); /* get a long from underlying stream */
  bool_t  (*x_putlong)(); /* put a long to  */
  bool_t  (*x_getbytes)();/* get some bytes from  */
  bool_t  (*x_putbytes)();/* put some bytes to  */
  u_int   (*x_getpostn)();/* returns bytes off from beginning */
  bool_t  (*x_setpostn)();/* lets you reposition the stream */
  long *  (*x_inline)();  /* buf quick ptr to buffered data */

 while we're used to one with type matching buf: int32_t*:

 If you're serious about getting rid of warnings even on mingw,
 here's one approach:

 I guess I'd agree with Dan that the best place to fix this is in
 PortableXDR itself.

 Converting that 'long *' - 'int32_t *' should be OK I think?  Unless
 that x_inline member is used for other XDR types.

For libvirt it's certainly ok, since the includer can ensure
that int32_t is always defined via gnulib's stdint.h.

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


[libvirt] [PATCH] 0/7 host (node) device enumeration - completed submission

2008-10-27 Thread David Lively
Since the version of this I posted last week still had some outstaning
TODO items that I have since finished, I'm re-submitting the whole
thing.  I consider this a complete submission since I don't think it's
necessary to implement any additional functionality to make this
acceptable.  (The two remaining unimplemented items are
virNodeDeviceCreate / Destroy and a real Devkit impl, neither of which
needs to be done immediately, for reasons discussed earlier.)

These patches implement the node device enumeration functionality, as
discussed here:
https://www.redhat.com/archives/libvir-list/2008-September/msg00398.html

I've broken it into the following pieces:
  1-public-api  additions to the public API
  2-internal-apiadditions to the internal API
  3-local-node-drivers  the HAL  DeviceKit implementations
  4-remote-node-driver  the remote driver
  5-virsh-support   virsh support
  6-python-bindings python bindings
  7-java-bindings   Java bindings (for libvirt-java)

Dave


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


[libvirt] one more warning

2008-10-27 Thread Jim Meyering
One more warning question:
Compiling with all storage backends disabled, I get this:

storage_backend.c:91: warning: comparison of unsigned expression  0 is always 
false

That's because of this code:

static virStorageBackendPtr backends[] = {
#if WITH_STORAGE_DIR
virStorageBackendDirectory,
#endif
#if WITH_STORAGE_FS
virStorageBackendFileSystem,
virStorageBackendNetFileSystem,
#endif
#if WITH_STORAGE_LVM
virStorageBackendLogical,
#endif
#if WITH_STORAGE_ISCSI
virStorageBackendISCSI,
#endif
#if WITH_STORAGE_DISK
virStorageBackendDisk,
#endif
};


virStorageBackendPtr
virStorageBackendForType(int type) {
unsigned int i;
for (i = 0 ; i  ARRAY_CARDINALITY(backends); i++)
if (backends[i]-type == type)
return backends[i];

virStorageReportError(NULL, VIR_ERR_INTERNAL_ERROR,
  _(missing backend for pool type %d), type);
return NULL;
}

The above loses because ARRAY_CARDINALITY(backends) is 0.

One solution is to always have at least one backend,
e.g., the first one, in which case, this patch works fine:
[but if you like this (i don't), it'd make sense also to remove the
configure-time option ]

diff --git a/src/storage_backend.c b/src/storage_backend.c
index e33f98c..264cc53 100644
--- a/src/storage_backend.c
+++ b/src/storage_backend.c
@@ -56,9 +56,7 @@
 #if WITH_STORAGE_DISK
 #include storage_backend_disk.h
 #endif
-#if WITH_STORAGE_DIR
 #include storage_backend_fs.h
-#endif

 VIR_ENUM_IMPL(virStorageBackendPartTable,
   VIR_STORAGE_POOL_DISK_LAST,
@@ -66,9 +64,7 @@ VIR_ENUM_IMPL(virStorageBackendPartTable,
   mac, bsd, pc98, sun, lvm2);

 static virStorageBackendPtr backends[] = {
-#if WITH_STORAGE_DIR
 virStorageBackendDirectory,
-#endif
 #if WITH_STORAGE_FS
 virStorageBackendFileSystem,
 virStorageBackendNetFileSystem,

Another way is to add a NULL pointer at the end
and change the loop not to use the array size at all:

for (i = 0; backends[i]; i++)
if (backends[i]-type == type)
return backends[i];

I chose the latter:

diff --git a/src/storage_backend.c b/src/storage_backend.c
index e33f98c..1f4ed10 100644
--- a/src/storage_backend.c
+++ b/src/storage_backend.c
@@ -82,13 +82,14 @@ static virStorageBackendPtr backends[] = {
 #if WITH_STORAGE_DISK
 virStorageBackendDisk,
 #endif
+NULL
 };


 virStorageBackendPtr
 virStorageBackendForType(int type) {
 unsigned int i;
-for (i = 0 ; i  ARRAY_CARDINALITY(backends); i++)
+for (i = 0; backends[i]; i++)
 if (backends[i]-type == type)
 return backends[i];

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


[libvirt] Re: [PATCH] 1/7 host (node) device enumeration - public API changes

2008-10-27 Thread David Lively
This patch contains the public API changes for host device enumeration.
diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index 97aea7d..0b0a4bc 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -995,6 +995,74 @@ virDomainPtrvirDomainCreateLinux(virConnectPtr conn,
  unsigned int flags);
 
 /*
+ * Host device enumeration
+ */
+
+/**
+ * virNodeDevice:
+ *
+ * A virNodeDevice contains a node (host) device details.
+ */
+
+typedef struct _virNodeDevice virNodeDevice;
+
+/**
+ * virNodeDevicePtr:
+ *
+ * A virNodeDevicePtr is a pointer to a virNodeDevice structure.  Get
+ * one via virNodeDeviceLookupByKey, virNodeDeviceLookupByName, or
+ * virNodeDeviceCreate.  Be sure to Call virNodeDeviceFree when done
+ * using a virNodeDevicePtr obtained from any of the above functions to
+ * avoid leaking memory.
+ */
+
+typedef virNodeDevice *virNodeDevicePtr;
+
+
+int virNodeNumOfDevices (virConnectPtr conn,
+ unsigned int flags);
+
+int virNodeListDevices  (virConnectPtr conn,
+ char **const names,
+ int maxnames,
+ unsigned int flags);
+
+int virNodeNumOfDevicesByCap (virConnectPtr conn,
+  const char *cap,
+  unsigned int flags);
+
+int virNodeListDevicesByCap (virConnectPtr conn,
+ const char *cap,
+ char **const names,
+ int maxnames,
+ unsigned int flags);
+
+virNodeDevicePtrvirNodeDeviceLookupByName (virConnectPtr conn,
+   const char *name);
+
+const char *virNodeDeviceGetName (virNodeDevicePtr dev);
+
+const char *virNodeDeviceGetParent   (virNodeDevicePtr dev);
+
+int virNodeDeviceNumOfCaps   (virNodeDevicePtr dev);
+
+int virNodeDeviceListCaps(virNodeDevicePtr dev,
+  char **const names,
+  int maxnames);
+
+char *  virNodeDeviceGetXMLDesc (virNodeDevicePtr dev,
+ unsigned int flags);
+
+virNodeDevicePtrvirNodeDeviceCreate (virConnectPtr conn,
+ const char *xml,
+ unsigned int flags);
+
+int virNodeDeviceDestroy(virNodeDevicePtr dev,
+ unsigned int flags);
+
+int virNodeDeviceFree   (virNodeDevicePtr dev);
+
+/*
  * Domain Event Notification
  */
 
diff --git a/include/libvirt/virterror.h b/include/libvirt/virterror.h
index 8e24708..020b8dc 100644
--- a/include/libvirt/virterror.h
+++ b/include/libvirt/virterror.h
@@ -58,6 +58,7 @@ typedef enum {
 VIR_FROM_STORAGE,   /* Error from storage driver */
 VIR_FROM_NETWORK,   /* Error from network config */
 VIR_FROM_DOMAIN,/* Error from domain config */
+VIR_FROM_NODE,  /* Error from node driver */
 } virErrorDomain;
 
 
@@ -148,6 +149,9 @@ typedef enum {
 VIR_WAR_NO_STORAGE, /* failed to start storage */
 VIR_ERR_NO_STORAGE_POOL, /* storage pool not found */
 VIR_ERR_NO_STORAGE_VOL, /* storage pool not found */
+VIR_WAR_NO_NODE, /* failed to start node driver */
+VIR_ERR_INVALID_NODE_DEVICE,/* invalid node device object */
+VIR_ERR_NO_NODE_DEVICE,/* node device not found */
 } virErrorNumber;
 
 /**
diff --git a/src/libvirt.c b/src/libvirt.c
index 8fd594b..8bf3b74 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -74,6 +74,8 @@ static virNetworkDriverPtr virNetworkDriverTab[MAX_DRIVERS];
 static int virNetworkDriverTabCount = 0;
 static virStorageDriverPtr virStorageDriverTab[MAX_DRIVERS];
 static int virStorageDriverTabCount = 0;
+static virNodeDriverPtr virNodeDriverTab[MAX_DRIVERS];
+static int virNodeDriverTabCount = 0;
 #ifdef WITH_LIBVIRTD
 static virStateDriverPtr virStateDriverTab[MAX_DRIVERS];
 static int virStateDriverTabCount = 0;
@@ -300,6 +302,19 @@ virInitialize(void)
 #ifdef WITH_NETWORK
 if (networkRegister() == -1) return -1;
 #endif
+#if defined(HAVE_HAL)  defined(HAVE_DEVKIT)
+/* Register only one of these two - they conflict */
+if (halNodeRegister() == -1)
+if (devkitNodeRegister() == -1)
+return -1;
+#else
+#ifdef HAVE_HAL
+if (halNodeRegister() == -1) return -1;
+#endif
+#ifdef HAVE_DEVKIT
+if 

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

2008-10-27 Thread David Lively
This patch contains additions to the internal API for host device
enumeration.
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 7ea1586..02aa343 100644
--- a/src/internal.h

[libvirt] Re: [PATCH] 3/7 host (node) device enumeration - HAL Devkit impls

2008-10-27 Thread David Lively
This patch contains the HAL-based implementation, and a preliminary
DeviceKit-based implementation, of node device enumeration.  The Devkit
impl is very incomplete, mostly because Devkit itself is very immature
at this stage.

diff --git a/configure.in b/configure.in
index 2d7fb14..3486a47 100644
--- a/configure.in
+++ b/configure.in
@@ -1048,6 +1048,93 @@ test $enable_shared = no  lt_cv_objdir=.
 LV_LIBTOOL_OBJDIR=${lt_cv_objdir-.}
 AC_SUBST([LV_LIBTOOL_OBJDIR])
 
+dnl HAL or DeviceKit library for host device enumeration
+HAL_REQUIRED=0.0
+HAL_CFLAGS=
+HAL_LIBS=
+AC_ARG_WITH([hal],
+  [  --with-hal use HAL for host device enumeration],
+  [],
+  [with_hal=check])
+
+if test x$with_hal = xyes -o x$with_hal = xcheck; then
+  PKG_CHECK_MODULES(HAL, hal = $HAL_REQUIRED,
+[with_hal=yes], [
+if test x$with_hal = xcheck ; then
+   with_hal=no
+else
+   AC_MSG_ERROR(
+ [You must install hal-devel = $HAL_REQUIRED to compile libvirt])
+fi
+  ])
+  if test x$with_hal = xyes ; then
+AC_DEFINE_UNQUOTED([HAVE_HAL], 1,
+  [use HAL for host device enumeration])
+
+old_CFLAGS=$CFLAGS
+old_LDFLAGS=$LDFLAGS
+CFLAGS=$CFLAGS $HAL_CFLAGS
+LDFLAGS=$LDFLAGS $HAL_LIBS
+AC_CHECK_FUNCS([libhal_get_all_devices],,[with_hal=no])
+CFLAGS=$old_CFLAGS
+LDFLAGS=$old_LDFLAGS
+  fi
+fi
+AM_CONDITIONAL([HAVE_HAL], [test x$with_hal = xyes])
+AC_SUBST([HAL_CFLAGS])
+AC_SUBST([HAL_LIBS])
+
+DEVKIT_REQUIRED=0.0
+DEVKIT_CFLAGS=
+DEVKIT_LIBS=
+AC_ARG_WITH([devkit],
+  [  --with-devkit  use DeviceKit for host device enumeration],
+  [],
+  [with_devkit=check])
+
+dnl Extra check needed while devkit pkg-config info missing glib2 dependency
+PKG_CHECK_MODULES(GLIB2, glib-2.0 = 0.0,,[
+  if test x$with_devkit = xcheck; then
+with_devkit=no
+  elif test x$with_devkit = xyes; then
+AC_MSG_ERROR([required package DeviceKit requires package glib-2.0])
+  fi])
+
+if test x$with_devkit = xyes -o x$with_devkit = xcheck; then
+  PKG_CHECK_MODULES(DEVKIT, devkit-gobject = $DEVKIT_REQUIRED,
+[with_devkit=yes], [
+if test x$with_devkit = xcheck ; then
+   with_devkit=no
+else
+   AC_MSG_ERROR(
+ [You must install DeviceKit-devel = $DEVKIT_REQUIRED to compile libvirt])
+fi
+  ])
+  if test x$with_devkit = xyes ; then
+AC_DEFINE_UNQUOTED([HAVE_DEVKIT], 1,
+  [use DeviceKit for host device enumeration])
+
+dnl Add glib2 flags explicitly while devkit pkg-config info missing glib2 dependency
+DEVKIT_CFLAGS=$GLIB2_CFLAGS $DEVKIT_CFLAGS
+DEVKIT_LIBS=$GLIB2_LIBS $DEVKIT_LIBS
+
+dnl Add more flags apparently required for devkit to work properly
+DEVKIT_CFLAGS=$DEVKIT_CFLAGS -D_POSIX_PTHREAD_SEMANTICS -D_REENTRANT
+
+old_CFLAGS=$CFLAGS
+old_LDFLAGS=$LDFLAGS
+CFLAGS=$CFLAGS $DEVKIT_CFLAGS
+LDFLAGS=$LDFLAGS $DEVKIT_LIBS
+AC_CHECK_FUNCS([devkit_client_connect],,[with_devkit=no])
+CFLAGS=$old_CFLAGS
+LDFLAGS=$old_LDFLAGS
+  fi
+fi
+AM_CONDITIONAL([HAVE_DEVKIT], [test x$with_devkit = xyes])
+AC_SUBST([DEVKIT_CFLAGS])
+AC_SUBST([DEVKIT_LIBS])
+
+
 # very annoying
 rm -f COPYING
 cp COPYING.LIB COPYING
@@ -1124,6 +1211,16 @@ AC_MSG_NOTICE([  numactl: $NUMACTL_CFLAGS $NUMACTL_LIBS])
 else
 AC_MSG_NOTICE([  numactl: no])
 fi
+if test $with_hal = yes ; then
+AC_MSG_NOTICE([  hal: $HAL_CFLAGS $HAL_LIBS])
+else
+AC_MSG_NOTICE([  hal: no])
+fi
+if test $with_devkit = yes ; then
+AC_MSG_NOTICE([  devkit: $DEVKIT_CFLAGS $DEVKIT_LIBS])
+else
+AC_MSG_NOTICE([  devkit: no])
+fi
 AC_MSG_NOTICE([])
 AC_MSG_NOTICE([Test suite])
 AC_MSG_NOTICE([])
diff --git a/po/POTFILES.in b/po/POTFILES.in
index f671155..684d300 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -12,6 +12,7 @@ src/lxc_controller.c
 src/lxc_driver.c
 src/network_conf.c
 src/network_driver.c
+src/node_device.c
 src/openvz_conf.c
 src/openvz_driver.c
 src/proxy_internal.c
diff --git a/src/Makefile.am b/src/Makefile.am
index 5a769f8..963a307 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,5 +1,22 @@
 ## Process this file with automake to produce Makefile.in
 
+if WITH_LIBVIRTD
+NODE_DEVICE_SOURCES = node_device.c node_device.h \
+		node_device_conf.c node_device_conf.h
+NODE_DEVICE_CFLAGS =
+NODE_DEVICE_LIBS =
+if HAVE_HAL
+NODE_DEVICE_CFLAGS += $(HAL_CFLAGS)
+NODE_DEVICE_LIBS += $(HAL_LIBS)
+NODE_DEVICE_SOURCES += node_device_hal.c
+endif
+if HAVE_DEVKIT
+NODE_DEVICE_CFLAGS += $(DEVKIT_CFLAGS)
+NODE_DEVICE_LIBS += $(DEVKIT_LIBS)
+NODE_DEVICE_SOURCES += node_device_devkit.c
+endif
+endif
+
 INCLUDES = \
 	   -I$(top_srcdir)/gnulib/lib -I../gnulib/lib \
 	   -I../include \
@@ -10,6 +27,7 @@ INCLUDES = \
 	   $(SASL_CFLAGS) \
 	   $(SELINUX_CFLAGS) \
 	   $(NUMACTL_CFLAGS) \
+	   $(NODE_DEVICE_CFLAGS) \
 	   -DBINDIR=\$(libexecdir)\ \
 	   -DSBINDIR=\$(sbindir)\ \
 	   -DSYSCONF_DIR=\$(sysconfdir)\ \
@@ -146,6 +164,7 @@ libvirt_la_SOURCES =		\
 		libvirt.c	\
 		$(GENERIC_LIB_SOURCES)\
 		$(DOMAIN_CONF_SOURCES)\
+		

[libvirt] Re: [PATCH] 4/7 host (node) device enumeration - remote driver

2008-10-27 Thread David Lively
This patch contains the remote implementation of node device
enumeration.

diff --git a/qemud/remote.c b/qemud/remote.c
index a623494..56d88a7 100644
--- a/qemud/remote.c
+++ b/qemud/remote.c
@@ -66,6 +66,7 @@ static void make_nonnull_domain (remote_nonnull_domain *dom_dst, virDomainPtr do
 static void make_nonnull_network (remote_nonnull_network *net_dst, virNetworkPtr net_src);
 static void make_nonnull_storage_pool (remote_nonnull_storage_pool *pool_dst, virStoragePoolPtr pool_src);
 static void make_nonnull_storage_vol (remote_nonnull_storage_vol *vol_dst, virStorageVolPtr vol_src);
+static void make_nonnull_node_device (remote_nonnull_node_device *dev_dst, virNodeDevicePtr dev_src);
 
 #include remote_dispatch_prototypes.h
 
@@ -3640,6 +3641,303 @@ remoteDispatchStorageVolLookupByPath (struct qemud_server *server ATTRIBUTE_UNUS
 }
 
 
+/***
+ * NODE INFO APIS
+ **/
+
+static int
+remoteDispatchNodeNumOfDevices (struct qemud_server *server ATTRIBUTE_UNUSED,
+struct qemud_client *client,
+remote_message_header *req,
+remote_node_num_of_devices_args *args,
+remote_node_num_of_devices_ret *ret)
+{
+CHECK_CONN(client);
+
+ret-num = virNodeNumOfDevices (client-conn, args-flags);
+if (ret-num == -1) return -1;
+
+return 0;
+}
+
+
+static int
+remoteDispatchNodeListDevices (struct qemud_server *server ATTRIBUTE_UNUSED,
+   struct qemud_client *client,
+   remote_message_header *req,
+   remote_node_list_devices_args *args,
+   remote_node_list_devices_ret *ret)
+{
+CHECK_CONN(client);
+
+if (args-maxnames  REMOTE_NODE_DEVICE_NAME_LIST_MAX) {
+remoteDispatchError (client, req,
+ %s, _(maxnames  REMOTE_NODE_DEVICE_NAME_LIST_MAX));
+return -2;
+}
+
+/* Allocate return buffer. */
+if (VIR_ALLOC_N(ret-names.names_val, args-maxnames)  0) {
+remoteDispatchSendError(client, req, VIR_ERR_NO_MEMORY, NULL);
+return -2;
+}
+
+ret-names.names_len =
+virNodeListDevices (client-conn,
+ret-names.names_val, args-maxnames, args-flags);
+if (ret-names.names_len == -1) {
+VIR_FREE(ret-names.names_val);
+return -1;
+}
+
+return 0;
+}
+
+
+static int
+remoteDispatchNodeNumOfDevicesByCap (struct qemud_server *server ATTRIBUTE_UNUSED,
+ struct qemud_client *client,
+ remote_message_header *req,
+ remote_node_num_of_devices_by_cap_args *args,
+ remote_node_num_of_devices_by_cap_ret *ret)
+{
+CHECK_CONN(client);
+
+ret-num = virNodeNumOfDevicesByCap (client-conn, args-cap, args-flags);
+if (ret-num == -1) return -1;
+
+return 0;
+}
+
+
+static int
+remoteDispatchNodeListDevicesByCap (struct qemud_server *server ATTRIBUTE_UNUSED,
+struct qemud_client *client,
+remote_message_header *req,
+remote_node_list_devices_by_cap_args *args,
+remote_node_list_devices_by_cap_ret *ret)
+{
+CHECK_CONN(client);
+
+if (args-maxnames  REMOTE_NODE_DEVICE_NAME_LIST_MAX) {
+remoteDispatchError (client, req,
+ %s, _(maxnames  REMOTE_NODE_DEVICE_NAME_LIST_MAX));
+return -2;
+}
+
+/* Allocate return buffer. */
+if (VIR_ALLOC_N(ret-names.names_val, args-maxnames)  0) {
+remoteDispatchSendError(client, req, VIR_ERR_NO_MEMORY, NULL);
+return -2;
+}
+
+ret-names.names_len =
+virNodeListDevicesByCap (client-conn, args-cap,
+ ret-names.names_val, args-maxnames,
+ args-flags);
+if (ret-names.names_len == -1) {
+VIR_FREE(ret-names.names_val);
+return -1;
+}
+
+return 0;
+}
+
+
+static int
+remoteDispatchNodeDeviceLookupByName (struct qemud_server *server ATTRIBUTE_UNUSED,
+  struct qemud_client *client,
+  remote_message_header *req,
+  remote_node_device_lookup_by_name_args *args,
+  remote_node_device_lookup_by_name_ret *ret)
+{
+virNodeDevicePtr dev;
+
+CHECK_CONN(client);
+
+dev = virNodeDeviceLookupByName (client-conn, args-name);
+if (dev == NULL) return -1;
+
+make_nonnull_node_device (ret-dev, dev);
+virNodeDeviceFree(dev);
+return 0;
+}
+
+
+static int

[libvirt] Re: [PATCH] 5/7 host (node) device enumeration - virsh support

2008-10-27 Thread David Lively
This patch contains virsh support for node device enumeration.

diff --git a/src/virsh.c b/src/virsh.c
index 89aa4fa..67963f0 100644
--- a/src/virsh.c
+++ b/src/virsh.c
@@ -4415,6 +4415,83 @@ cmdVersion(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED)
 }
 
 /*
+ * node-list-devices command
+ */
+static const vshCmdInfo info_node_list_devices[] = {
+{syntax, node-list-devices},
+{help, gettext_noop(enumerate devices on this host)},
+{NULL, NULL}
+};
+
+static int
+cmdNodeListDevices (vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED)
+{
+char **devices;
+int num_devices, i;
+
+if (!vshConnectionUsability(ctl, ctl-conn, TRUE))
+return FALSE;
+
+num_devices = virNodeNumOfDevices(ctl-conn, 0);
+if (num_devices  0) {
+vshError(ctl, FALSE, %s, _(Failed to count node devices));
+return FALSE;
+} else if (num_devices == 0) {
+return TRUE;
+}
+
+devices = vshMalloc(ctl, sizeof(char *) * num_devices);
+num_devices = virNodeListDevices(ctl-conn, devices, num_devices, 0);
+if (num_devices  0) {
+vshError(ctl, FALSE, %s, _(Failed to list node devices));
+free(devices);
+return FALSE;
+}
+for (i = 0; i  num_devices; i++) {
+vshPrint(ctl, %s\n, devices[i]);
+free(devices[i]);
+}
+free(devices);
+return TRUE;
+}
+
+/*
+ * node-device-dumpxml command
+ */
+static const vshCmdInfo info_node_device_dumpxml[] = {
+{syntax, node-device-dumpxml device},
+{help, gettext_noop(node device details in XML)},
+{desc, gettext_noop(Output the node device details as an XML dump to stdout.)},
+{NULL, NULL}
+};
+
+
+static const vshCmdOptDef opts_node_device_dumpxml[] = {
+{device, VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop(device key)},
+{NULL, 0, 0, NULL}
+};
+
+static int
+cmdNodeDeviceDumpXML (vshControl *ctl, const vshCmd *cmd)
+{
+const char *name;
+virNodeDevicePtr device;
+
+if (!vshConnectionUsability(ctl, ctl-conn, TRUE))
+return FALSE;
+if (!(name = vshCommandOptString(cmd, device, NULL)))
+return FALSE;
+if (!(device = virNodeDeviceLookupByName(ctl-conn, name))) {
+vshError(ctl, FALSE, %s '%s', _(Could not find matching device), name);
+return FALSE;
+}
+
+vshPrint(ctl, %s\n, virNodeDeviceGetXMLDesc(device, 0));
+virNodeDeviceFree(device);
+return TRUE;
+}
+
+/*
  * hostkey command
  */
 static const vshCmdInfo info_hostname[] = {
@@ -5566,6 +5643,9 @@ static const vshCmdDef commands[] = {
 {net-uuid, cmdNetworkUuid, opts_network_uuid, info_network_uuid},
 {nodeinfo, cmdNodeinfo, NULL, info_nodeinfo},
 
+{node-list-devices, cmdNodeListDevices, NULL, info_node_list_devices},
+{node-device-dumpxml, cmdNodeDeviceDumpXML, opts_node_device_dumpxml, info_node_device_dumpxml},
+
 {pool-autostart, cmdPoolAutostart, opts_pool_autostart, info_pool_autostart},
 {pool-build, cmdPoolBuild, opts_pool_build, info_pool_build},
 {pool-create, cmdPoolCreate, opts_pool_create, info_pool_create},
--
Libvir-list mailing list
Libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] Re: [PATCH] 6/7 host (node) device enumeration - python bindings

2008-10-27 Thread David Lively
This patch contains python bindings for node device enumeration.

diff --git a/python/generator.py b/python/generator.py
index ca83eaf..108dfc2 100755
--- a/python/generator.py
+++ b/python/generator.py
@@ -258,6 +258,11 @@ py_types = {
 'const virConnectPtr':  ('O', virConnect, virConnectPtr, virConnectPtr),
 'virConnect *':  ('O', virConnect, virConnectPtr, virConnectPtr),
 'const virConnect *':  ('O', virConnect, virConnectPtr, virConnectPtr),
+
+'virNodeDevicePtr':  ('O', virNodeDevice, virNodeDevicePtr, virNodeDevicePtr),
+'const virNodeDevicePtr':  ('O', virNodeDevice, virNodeDevicePtr, virNodeDevicePtr),
+'virNodeDevice *':  ('O', virNodeDevice, virNodeDevicePtr, virNodeDevicePtr),
+'const virNodeDevice *':  ('O', virNodeDevice, virNodeDevicePtr, virNodeDevicePtr),
 }
 
 py_return_types = {
@@ -315,6 +320,9 @@ skip_impl = (
 'virStoragePoolListVolumes',
 'virDomainBlockPeek',
 'virDomainMemoryPeek',
+'virNodeListDevicesByCap',
+'virNodeListDevices',
+'virNodeDeviceListCaps',
 )
 
 
@@ -599,6 +607,8 @@ classes_type = {
 virStoragePool *: (._o, virStoragePool(self, _obj=%s), virStoragePool),
 virStorageVolPtr: (._o, virStorageVol(self, _obj=%s), virStorageVol),
 virStorageVol *: (._o, virStorageVol(self, _obj=%s), virStorageVol),
+virNodeDevicePtr: (._o, virNodeDevice(self, _obj=%s), virNodeDevice),
+virNodeDevice *: (._o, virNodeDevice(self, _obj=%s), virNodeDevice),
 virConnectPtr: (._o, virConnect(_obj=%s), virConnect),
 virConnect *: (._o, virConnect(_obj=%s), virConnect),
 }
@@ -606,7 +616,8 @@ classes_type = {
 converter_type = {
 }
 
-primary_classes = [virDomain, virNetwork, virStoragePool, virStorageVol, virConnect]
+primary_classes = [virDomain, virNetwork, virStoragePool, virStorageVol,
+   virConnect, virNodeDevice ]
 
 classes_ancestor = {
 }
@@ -616,6 +627,7 @@ classes_destructors = {
 virStoragePool: virStoragePoolFree,
 virStorageVol: virStorageVolFree,
 virConnect: virConnectClose,
+virNodeDevice : virNodeDeviceFree
 }
 
 functions_noexcept = {
@@ -625,6 +637,8 @@ functions_noexcept = {
 'virStoragePoolGetName': True,
 'virStorageVolGetName': True,
 'virStorageVolGetkey': True,
+'virNodeDeviceGetName': True,
+'virNodeDeviceGetParent': True,
 }
 
 reference_keepers = {
@@ -705,6 +719,13 @@ def nameFixup(name, classe, type, file):
 elif name[0:13] == virStorageVol:
 func = name[13:]
 func = string.lower(func[0:1]) + func[1:]
+elif name[0:13] == virNodeDevice:
+if name[13:16] == Get:
+func = string.lower(name[16]) + name[17:]
+elif name[13:19] == Lookup or name[13:] == Create:
+func = string.lower(name[3]) + name[4:]
+else:
+func = string.lower(name[13]) + name[14:]
 elif name[0:7] == virNode:
 func = name[7:]
 func = string.lower(func[0:1]) + func[1:]
@@ -957,7 +978,7 @@ def buildWrappers():
 	else:
 		txt.write(Class %s()\n % (classname))
 		classes.write(class %s:\n % (classname))
-if classname in [ virDomain, virNetwork, virStoragePool, virStorageVol ]:
+if classname in [ virDomain, virNetwork, virStoragePool, virStorageVol, virNodeDevice ]:
 classes.write(def __init__(self, conn, _obj=None):\n)
 else:
 classes.write(def __init__(self, _obj=None):\n)
@@ -965,7 +986,7 @@ def buildWrappers():
 		list = reference_keepers[classname]
 		for ref in list:
 		classes.write(self.%s = None\n % ref[1])
-if classname in [ virDomain, virNetwork ]:
+if classname in [ virDomain, virNetwork, virNodeDevice ]:
 classes.write(self._conn = conn\n)
 elif classname in [ virStorageVol, virStoragePool ]:
 classes.write(self._conn = conn\n + \
diff --git a/python/libvir.c b/python/libvir.c
index 9cc0c81..7b2792e 100644
--- a/python/libvir.c
+++ b/python/libvir.c
@@ -1466,7 +1466,130 @@ libvirt_virStoragePoolLookupByUUID(PyObject *self ATTRIBUTE_UNUSED, PyObject *ar
 return(py_retval);
 }
 
+static PyObject *
+libvirt_virNodeListDevices(PyObject *self ATTRIBUTE_UNUSED,
+   PyObject *args) {
+PyObject *py_retval;
+char **names = NULL;
+int c_retval, i;
+virConnectPtr conn;
+PyObject *pyobj_conn;
+unsigned int flags;
+
+
+if (!PyArg_ParseTuple(args, (char *)Oi:virNodeListDevices, pyobj_conn, flags))
+return(NULL);
+conn = (virConnectPtr) PyvirConnect_Get(pyobj_conn);
+
+c_retval = virNodeNumOfDevices(conn, flags);
+if (c_retval  0)
+return VIR_PY_NONE;
+
+if (c_retval) {
+names = malloc(sizeof(*names) * c_retval);
+if (!names)
+return VIR_PY_NONE;
+c_retval = virNodeListDevices(conn, names, c_retval, flags);
+if (c_retval  0) 

[libvirt] Re: [PATCH] 7/7 host (node) device enumeration - java bindings

2008-10-27 Thread David Lively
This patch (for libvirt-java) contains Java bindings for node device
enumeration.

diff --git a/src/Makefile.am b/src/Makefile.am
index 5200c1d..466a0eb 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -14,6 +14,7 @@ java_libvirt_source_files = \
   org/libvirt/Error.java \
   org/libvirt/Network.java \
   org/libvirt/NodeInfo.java \
+  org/libvirt/NodeDevice.java \
   org/libvirt/SchedBooleanParameter.java \
   org/libvirt/SchedDoubleParameter.java \
   org/libvirt/SchedIntParameter.java \
diff --git a/src/jni/Makefile.am b/src/jni/Makefile.am
index 6e19384..8feed24 100644
--- a/src/jni/Makefile.am
+++ b/src/jni/Makefile.am
@@ -10,7 +10,8 @@ GENERATED = \
   org_libvirt_StoragePool.h \
   org_libvirt_StorageVol_Type.h \
   org_libvirt_StorageVol_DeleteFlags.h \
-  org_libvirt_StorageVol.h
+  org_libvirt_StorageVol.h \
+  org_libvirt_NodeDevice.h
 
 BUILT_SOURCES = $(GENERATED)
 
@@ -31,6 +32,9 @@ org_libvirt_StoragePool.h org_libvirt_StoragePool_BuildFlags.h org_libvirt_Stora
 org_libvirt_StorageVol.h org_libvirt_StorageVol_Type.h org_libvirt_StorageVol_DeleteFlags.h : $(JAVA_CLASS_ROOT)/org/libvirt/StorageVol.class
 	$(JAVAH) -classpath $(JAVA_CLASS_ROOT) org.libvirt.StorageVol
 
+org_libvirt_NodeDevice.h : $(JAVA_CLASS_ROOT)/org/libvirt/NodeDevice.class
+	$(JAVAH) -classpath $(JAVA_CLASS_ROOT) org.libvirt.NodeDevice
+
 lib_LTLIBRARIES = libvirt_jni.la
 libvirt_jni_la_SOURCES = \
   org_libvirt_Network.c \
@@ -38,6 +42,7 @@ libvirt_jni_la_SOURCES = \
   org_libvirt_Domain.c \
   org_libvirt_StoragePool.c \
   org_libvirt_StorageVol.c \
+  org_libvirt_NodeDevice.c \
   generic.h \
   ErrorHandler.c \
   ErrorHandler.h \
diff --git a/src/jni/generic.h b/src/jni/generic.h
index 347c076..e1da179 100644
--- a/src/jni/generic.h
+++ b/src/jni/generic.h
@@ -70,6 +70,16 @@
 	return retval;
 
 /*
+ * Generic macro with a VIROBJ and a String and an int arguments
+ * returning an int
+ */
+#define GENERIC_VIROBJ_STRING_INT__INT(ENV, OBJ, VIROBJ, J_STR, ARG1, VIRFUNC1) \
+	const char *str=(*ENV)-GetStringUTFChars(ENV, J_STR, NULL); \
+	jint retval = (jlong)VIRFUNC1(VIROBJ, str, ARG1);	 \
+	(*ENV)-ReleaseStringUTFChars(ENV, J_STR, str);		 \
+	return retval;
+
+/*
  * Generic macro with a VIROBJ and an String arguments returning a virObject
  * (for functions like *CreateXML* that take no flags)
  */
@@ -81,15 +91,14 @@
 
 /*
  * Generic macro with a VIROBJ and String and int arguments returning a
- * virObject (for functions like *CreateXML* that take a flags)
+ * virObject
  */
-#define GENERIC_VIROBJ_STRING_INT__VIROBJ(ENV, OBJ, VIROBJ, J_XMLDESC, FLAGS, VIRFUNC1) \
-	const char *xmlDesc=(*ENV)-GetStringUTFChars(ENV, J_XMLDESC, NULL); \
-	jlong retval = (jlong)VIRFUNC1(VIROBJ, xmlDesc, FLAGS);		\
-	(*ENV)-ReleaseStringUTFChars(ENV, J_XMLDESC, xmlDesc);		\
+#define GENERIC_VIROBJ_STRING_INT__VIROBJ(ENV, OBJ, VIROBJ, J_STR, ARG1, VIRFUNC1) \
+	const char *str=(*ENV)-GetStringUTFChars(ENV, J_STR, NULL);	\
+	jlong retval = (jlong)VIRFUNC1(VIROBJ, str, ARG1);		\
+	(*ENV)-ReleaseStringUTFChars(ENV, J_STR, str);			\
 	return retval;
 
-
 /*
  * Generic macro for the *getAutoStart functions
  */
@@ -150,6 +159,61 @@
 	return j_names;
 
 /*
+ * Generic macro for the *List* functions that return an array of strings
+ * and take a single int arg.
+ * VIRFUNC1 is the *List* function
+ * VIRFUNC2 is the corresponding *NumOf* function
+ */
+#define GENERIC_INT__LIST_STRINGARRAY(ENV, OBJ, VIROBJ, JINT, VF1, VF2) \
+	int maxnames;			\
+	char **names;			\
+	int c;\
+	jobjectArray j_names=NULL;	\
+	if((maxnames = VF2(VIROBJ, JINT))0)\
+		return NULL;		\
+	names= (char**)calloc(maxnames, sizeof(char*));			\
+	if(VF1(VIROBJ, names, maxnames, JINT)=0){			\
+		j_names= (jobjectArray)(*ENV)-NewObjectArray(ENV, maxnames, \
+			(*ENV)-FindClass(ENV,java/lang/String),	\
+			(*ENV)-NewStringUTF(ENV,));			\
+		for(c=0; cmaxnames; c++){\
+			(*ENV)-SetObjectArrayElement(ENV, j_names, c,	\
+			(*ENV)-NewStringUTF(ENV, names[c]));		\
+		}			\
+	}\
+	free(names);			\
+	return j_names;
+
+/*
+ * Generic macro for the *List* functions that return an array of strings
+ * and take a single string arg and an int arg.
+ * VIRFUNC1 is the *List* function
+ * VIRFUNC2 is the corresponding *NumOf* function
+ */
+#define GENERIC_STRING_INT__LIST_STRINGARRAY(ENV, OBJ, VIROBJ, J_STR, JINT, VF1, VF2) \
+	int maxnames;			\
+	char **names;			\
+	int c;\
+	jobjectArray j_names=NULL;	\
+	const char *str = (*ENV)-GetStringUTFChars(ENV, J_STR, NULL);	\
+	if((maxnames = VF2(VIROBJ, str, JINT))0)			\
+		goto cleanup;		\
+	names= (char**)calloc(maxnames, sizeof(char*));			\
+	if(VF1(VIROBJ, str, names, maxnames, JINT)=0){			\
+		j_names= (jobjectArray)(*ENV)-NewObjectArray(ENV, maxnames, \
+			(*ENV)-FindClass(ENV,java/lang/String),	\
+			(*ENV)-NewStringUTF(ENV,));			\
+		for(c=0; cmaxnames; c++){\
+			(*ENV)-SetObjectArrayElement(ENV, j_names, c,	\
+			(*ENV)-NewStringUTF(ENV,