Re: [libvirt] mingw warnings
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
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
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
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
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
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
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
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
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
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
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,