summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDaniel P. Berrange <berrange@redhat.com>2008-11-21 12:20:45 +0000
committerDaniel P. Berrange <berrange@redhat.com>2008-11-21 12:20:45 +0000
commit149322c530c3d7cfe9f357e4c4a6c755d40b11cd (patch)
treea9617eb9fa72fb8d8938692dca29b0d4475bcfec /src
parentPublic API for node device enumeration (David Lively) (diff)
downloadlibvirt-149322c530c3d7cfe9f357e4c4a6c755d40b11cd.tar.gz
libvirt-149322c530c3d7cfe9f357e4c4a6c755d40b11cd.tar.bz2
libvirt-149322c530c3d7cfe9f357e4c4a6c755d40b11cd.zip
Internal APIs for handling node device XML configuration (David Lively)
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am8
-rw-r--r--src/node_device_conf.c404
-rw-r--r--src/node_device_conf.h195
3 files changed, 606 insertions, 1 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index a7ae633ac..0e9e71d20 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -136,6 +136,10 @@ STORAGE_DRIVER_SOURCES = \
storage_driver.h storage_driver.c \
storage_backend.h storage_backend.c
+# Network driver generic impl APIs
+NODE_DEVICE_CONF_SOURCES = \
+ node_device_conf.c node_device_conf.h
+
STORAGE_DRIVER_FS_SOURCES = \
storage_backend_fs.h storage_backend_fs.c
@@ -171,7 +175,9 @@ libvirt_driver_la_SOURCES = \
$(DRIVER_SOURCES) \
$(DOMAIN_CONF_SOURCES) \
$(NETWORK_CONF_SOURCES) \
- $(STORAGE_CONF_SOURCES)
+ $(STORAGE_CONF_SOURCES) \
+ $(NODE_DEVICE_CONF_SOURCES)
+
libvirt_driver_la_CFLAGS = $(XEN_CFLAGS)
libvirt_driver_la_LDFLAGS = $(XEN_LIBS)
diff --git a/src/node_device_conf.c b/src/node_device_conf.c
new file mode 100644
index 000000000..d04b73d29
--- /dev/null
+++ b/src/node_device_conf.c
@@ -0,0 +1,404 @@
+/*
+ * node_device_conf.c: config handling for node devices
+ *
+ * Copyright (C) 2008 Virtual Iron Software, Inc.
+ * Copyright (C) 2008 David F. Lively
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: David F. Lively <dlively@virtualiron.com>
+ */
+
+#include <config.h>
+
+#include <unistd.h>
+#include <errno.h>
+
+#include "virterror_internal.h"
+#include "memory.h"
+
+#include "node_device_conf.h"
+#include "memory.h"
+#include "xml.h"
+#include "util.h"
+#include "buf.h"
+#include "uuid.h"
+
+
+VIR_ENUM_IMPL(virNodeDevCap, VIR_NODE_DEV_CAP_LAST,
+ "system",
+ "pci",
+ "usb_device",
+ "usb",
+ "net",
+ "block",
+ "scsi_host",
+ "scsi",
+ "storage");
+
+VIR_ENUM_IMPL(virNodeDevNetCap, VIR_NODE_DEV_CAP_NET_LAST,
+ "80203",
+ "80211");
+
+
+#define virNodeDeviceLog(msg...) fprintf(stderr, msg)
+
+virNodeDeviceObjPtr virNodeDeviceFindByName(const virNodeDeviceObjListPtr devs,
+ const char *name)
+{
+ unsigned int i;
+
+ for (i = 0; i < devs->count; i++)
+ if (STREQ(devs->objs[i]->def->name, name))
+ return devs->objs[i];
+
+ return NULL;
+}
+
+
+void virNodeDeviceDefFree(virNodeDeviceDefPtr def)
+{
+ virNodeDevCapsDefPtr caps;
+
+ if (!def)
+ return;
+
+ VIR_FREE(def->name);
+ VIR_FREE(def->parent);
+
+ caps = def->caps;
+ while (caps) {
+ virNodeDevCapsDefPtr next = caps->next;
+ virNodeDevCapsDefFree(caps);
+ caps = next;
+ }
+
+ VIR_FREE(def);
+}
+
+void virNodeDeviceObjFree(virNodeDeviceObjPtr dev)
+{
+ if (!dev)
+ return;
+
+ virNodeDeviceDefFree(dev->def);
+ if (dev->privateFree)
+ (*dev->privateFree)(dev->privateData);
+
+ VIR_FREE(dev);
+}
+
+void virNodeDeviceObjListFree(virNodeDeviceObjListPtr devs)
+{
+ unsigned int i;
+ for (i = 0 ; i < devs->count ; i++)
+ virNodeDeviceObjFree(devs->objs[i]);
+ VIR_FREE(devs->objs);
+ devs->count = 0;
+}
+
+virNodeDeviceObjPtr virNodeDeviceAssignDef(virConnectPtr conn,
+ virNodeDeviceObjListPtr devs,
+ const virNodeDeviceDefPtr def)
+{
+ virNodeDeviceObjPtr device;
+
+ if ((device = virNodeDeviceFindByName(devs, def->name))) {
+ virNodeDeviceDefFree(device->def);
+ device->def = def;
+ return device;
+ }
+
+ if (VIR_ALLOC(device) < 0) {
+ virNodeDeviceReportError(conn, VIR_ERR_NO_MEMORY, NULL);
+ return NULL;
+ }
+
+ device->def = def;
+
+ if (VIR_REALLOC_N(devs->objs, devs->count+1) < 0) {
+ device->def = NULL;
+ virNodeDeviceObjFree(device);
+ virNodeDeviceReportError(conn, VIR_ERR_NO_MEMORY, NULL);
+ return NULL;
+ }
+ devs->objs[devs->count++] = device;
+
+ return device;
+
+}
+
+void virNodeDeviceObjRemove(virNodeDeviceObjListPtr devs,
+ const virNodeDeviceObjPtr dev)
+{
+ unsigned int i;
+
+ for (i = 0; i < devs->count; i++) {
+ if (devs->objs[i] == dev) {
+ virNodeDeviceObjFree(devs->objs[i]);
+
+ if (i < (devs->count - 1))
+ memmove(devs->objs + i, devs->objs + i + 1,
+ sizeof(*(devs->objs)) * (devs->count - (i + 1)));
+
+ if (VIR_REALLOC_N(devs->objs, devs->count - 1) < 0) {
+ ; /* Failure to reduce memory allocation isn't fatal */
+ }
+ devs->count--;
+
+ break;
+ }
+ }
+}
+
+char *virNodeDeviceDefFormat(virConnectPtr conn,
+ const virNodeDeviceDefPtr def)
+{
+ virBuffer buf = VIR_BUFFER_INITIALIZER;
+ virNodeDevCapsDefPtr caps = def->caps;
+ char *tmp;
+
+ virBufferAddLit(&buf, "<device>\n");
+ virBufferEscapeString(&buf, " <name>%s</name>\n", def->name);
+
+ if (def->parent)
+ virBufferEscapeString(&buf, " <parent>%s</parent>\n", def->parent);
+
+ for (caps = def->caps; caps; caps = caps->next) {
+ char uuidstr[VIR_UUID_STRING_BUFLEN];
+ union _virNodeDevCapData *data = &caps->data;
+
+ virBufferVSprintf(&buf, " <capability type='%s'>\n",
+ virNodeDevCapTypeToString(caps->type));
+ switch (caps->type) {
+ case VIR_NODE_DEV_CAP_SYSTEM:
+ if (data->system.product_name)
+ virBufferEscapeString(&buf, " <product>%s</product>\n",
+ data->system.product_name);
+ virBufferAddLit(&buf, " <hardware>\n");
+ if (data->system.hardware.vendor_name)
+ virBufferEscapeString(&buf, " <vendor>%s</vendor>\n",
+ data->system.hardware.vendor_name);
+ if (data->system.hardware.version)
+ virBufferEscapeString(&buf, " <version>%s</version>\n",
+ data->system.hardware.version);
+ if (data->system.hardware.serial)
+ virBufferEscapeString(&buf, " <serial>%s</serial>\n",
+ data->system.hardware.serial);
+ virUUIDFormat(data->system.hardware.uuid, uuidstr);
+ virBufferVSprintf(&buf, " <uuid>%s</uuid>\n", uuidstr);
+ virBufferAddLit(&buf, " </hardware>\n");
+ virBufferAddLit(&buf, " <firmware>\n");
+ if (data->system.firmware.vendor_name)
+ virBufferEscapeString(&buf, " <vendor>%s</vendor>\n",
+ data->system.firmware.vendor_name);
+ if (data->system.firmware.version)
+ virBufferEscapeString(&buf, " <version>%s</version>\n",
+ data->system.firmware.version);
+ if (data->system.firmware.release_date)
+ virBufferEscapeString(&buf,
+ " <release_date>%s</release_date>\n",
+ data->system.firmware.release_date);
+ virBufferAddLit(&buf, " </firmware>\n");
+ break;
+ case VIR_NODE_DEV_CAP_PCI_DEV:
+ virBufferVSprintf(&buf, " <domain>%d</domain>\n",
+ data->pci_dev.domain);
+ virBufferVSprintf(&buf, " <bus>%d</bus>\n", data->pci_dev.bus);
+ virBufferVSprintf(&buf, " <slot>%d</slot>\n",
+ data->pci_dev.slot);
+ virBufferVSprintf(&buf, " <function>%d</function>\n",
+ data->pci_dev.function);
+ virBufferVSprintf(&buf, " <product id='%d'",
+ data->pci_dev.product);
+ if (data->pci_dev.product_name)
+ virBufferEscapeString(&buf, ">%s</product>\n",
+ data->pci_dev.product_name);
+ else
+ virBufferAddLit(&buf, " />\n");
+ virBufferVSprintf(&buf, " <vendor id='%d'",
+ data->pci_dev.vendor);
+ if (data->pci_dev.vendor_name)
+ virBufferEscapeString(&buf, ">%s</vendor>\n",
+ data->pci_dev.vendor_name);
+ else
+ virBufferAddLit(&buf, " />\n");
+ break;
+ case VIR_NODE_DEV_CAP_USB_DEV:
+ virBufferVSprintf(&buf, " <bus>%d</bus>\n", data->usb_dev.bus);
+ virBufferVSprintf(&buf, " <device>%d</device>\n",
+ data->usb_dev.device);
+ virBufferVSprintf(&buf, " <product id='%d'",
+ data->usb_dev.product);
+ if (data->usb_dev.product_name)
+ virBufferEscapeString(&buf, ">%s</product>\n",
+ data->usb_dev.product_name);
+ else
+ virBufferAddLit(&buf, " />\n");
+ virBufferVSprintf(&buf, " <vendor id='%d'",
+ data->usb_dev.vendor);
+ if (data->usb_dev.vendor_name)
+ virBufferEscapeString(&buf, ">%s</vendor>\n",
+ data->usb_dev.vendor_name);
+ else
+ virBufferAddLit(&buf, " />\n");
+ break;
+ case VIR_NODE_DEV_CAP_USB_INTERFACE:
+ virBufferVSprintf(&buf, " <number>%d</number>\n",
+ data->usb_if.number);
+ virBufferVSprintf(&buf, " <class>%d</class>\n",
+ data->usb_if._class);
+ virBufferVSprintf(&buf, " <subclass>%d</subclass>\n",
+ data->usb_if.subclass);
+ virBufferVSprintf(&buf, " <protocol>%d</protocol>\n",
+ data->usb_if.protocol);
+ if (data->usb_if.description)
+ virBufferVSprintf(&buf, " <description>%s</description>\n",
+ data->usb_if.description);
+ break;
+ case VIR_NODE_DEV_CAP_NET:
+ virBufferVSprintf(&buf, " <interface>%s</interface>\n",
+ data->net.interface);
+ if (data->net.address)
+ virBufferVSprintf(&buf, " <address>%s</address>\n",
+ data->net.address);
+ if (data->net.subtype != VIR_NODE_DEV_CAP_NET_LAST) {
+ const char *subtyp =
+ virNodeDevNetCapTypeToString(data->net.subtype);
+ virBufferVSprintf(&buf, " <capability type='%s'/>\n", subtyp);
+ }
+ break;
+ case VIR_NODE_DEV_CAP_BLOCK:
+ virBufferVSprintf(&buf, " <device>%s</device>\n",
+ data->block.device);
+ break;
+ case VIR_NODE_DEV_CAP_SCSI_HOST:
+ virBufferVSprintf(&buf, " <host>%d</host>\n",
+ data->scsi_host.host);
+ break;
+ case VIR_NODE_DEV_CAP_SCSI:
+ virBufferVSprintf(&buf, " <host>%d</host>\n", data->scsi.host);
+ virBufferVSprintf(&buf, " <bus>%d</bus>\n", data->scsi.bus);
+ virBufferVSprintf(&buf, " <target>%d</target>\n",
+ data->scsi.target);
+ virBufferVSprintf(&buf, " <lun>%d</lun>\n", data->scsi.lun);
+ if (data->scsi.type)
+ virBufferVSprintf(&buf, " <type>%s</type>\n",
+ data->scsi.type);
+ break;
+ case VIR_NODE_DEV_CAP_STORAGE:
+ if (data->storage.bus)
+ virBufferVSprintf(&buf, " <bus>%s</bus>\n",
+ data->storage.bus);
+ if (data->storage.drive_type)
+ virBufferVSprintf(&buf, " <drive_type>%s</drive_type>\n",
+ data->storage.drive_type);
+ if (data->storage.model)
+ virBufferVSprintf(&buf, " <model>%s</model>\n",
+ data->storage.model);
+ if (data->storage.vendor)
+ virBufferVSprintf(&buf, " <vendor>%s</vendor>\n",
+ data->storage.vendor);
+ if (data->storage.flags & VIR_NODE_DEV_CAP_STORAGE_REMOVABLE) {
+ int avl = data->storage.flags &
+ VIR_NODE_DEV_CAP_STORAGE_REMOVABLE_MEDIA_AVAILABLE;
+ virBufferAddLit(&buf, " <capability type='removable'>\n");
+ virBufferVSprintf(&buf,
+ " <media_available>%d"
+ "</media_available>\n", avl ? 1 : 0);
+ virBufferVSprintf(&buf, " <media_size>%llu</media_size>\n",
+ data->storage.removable_media_size);
+ virBufferAddLit(&buf, " </capability>\n");
+ } else {
+ virBufferVSprintf(&buf, " <size>%llu</size>\n",
+ data->storage.size);
+ }
+ if (data->storage.flags & VIR_NODE_DEV_CAP_STORAGE_HOTPLUGGABLE)
+ virBufferAddLit(&buf,
+ " <capability type='hotpluggable' />\n");
+ break;
+ case VIR_NODE_DEV_CAP_LAST:
+ /* ignore special LAST value */
+ break;
+ }
+
+ virBufferAddLit(&buf, " </capability>\n");
+ }
+
+ virBufferAddLit(&buf, "</device>\n");
+
+ if (virBufferError(&buf))
+ goto no_memory;
+
+ return virBufferContentAndReset(&buf);
+
+ no_memory:
+ virNodeDeviceReportError(conn, VIR_ERR_NO_MEMORY, NULL);
+ tmp = virBufferContentAndReset(&buf);
+ VIR_FREE(tmp);
+ return NULL;
+}
+
+void virNodeDevCapsDefFree(virNodeDevCapsDefPtr caps)
+{
+ union _virNodeDevCapData *data = &caps->data;
+
+ switch (caps->type) {
+ case VIR_NODE_DEV_CAP_SYSTEM:
+ VIR_FREE(data->system.product_name);
+ VIR_FREE(data->system.hardware.vendor_name);
+ VIR_FREE(data->system.hardware.version);
+ VIR_FREE(data->system.hardware.serial);
+ VIR_FREE(data->system.firmware.vendor_name);
+ VIR_FREE(data->system.firmware.version);
+ VIR_FREE(data->system.firmware.release_date);
+ break;
+ case VIR_NODE_DEV_CAP_PCI_DEV:
+ VIR_FREE(data->pci_dev.product_name);
+ VIR_FREE(data->pci_dev.vendor_name);
+ break;
+ case VIR_NODE_DEV_CAP_USB_DEV:
+ VIR_FREE(data->usb_dev.product_name);
+ VIR_FREE(data->usb_dev.vendor_name);
+ break;
+ case VIR_NODE_DEV_CAP_USB_INTERFACE:
+ VIR_FREE(data->usb_if.description);
+ break;
+ case VIR_NODE_DEV_CAP_NET:
+ VIR_FREE(data->net.interface);
+ VIR_FREE(data->net.address);
+ break;
+ case VIR_NODE_DEV_CAP_BLOCK:
+ VIR_FREE(data->block.device);
+ break;
+ case VIR_NODE_DEV_CAP_SCSI_HOST:
+ break;
+ case VIR_NODE_DEV_CAP_SCSI:
+ VIR_FREE(data->scsi.type);
+ break;
+ case VIR_NODE_DEV_CAP_STORAGE:
+ VIR_FREE(data->storage.bus);
+ VIR_FREE(data->storage.drive_type);
+ VIR_FREE(data->storage.model);
+ VIR_FREE(data->storage.vendor);
+ break;
+ case VIR_NODE_DEV_CAP_LAST:
+ /* This case is here to shutup the compiler */
+ break;
+ }
+
+ VIR_FREE(caps);
+}
+
diff --git a/src/node_device_conf.h b/src/node_device_conf.h
new file mode 100644
index 000000000..abb176838
--- /dev/null
+++ b/src/node_device_conf.h
@@ -0,0 +1,195 @@
+/*
+ * node_device_conf.h: config handling for node devices
+ *
+ * Copyright (C) 2008 Virtual Iron Software, Inc.
+ * Copyright (C) 2008 David F. Lively
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: David F. Lively <dlively@virtualiron.com>
+ */
+
+#ifndef __VIR_NODE_DEVICE_CONF_H__
+#define __VIR_NODE_DEVICE_CONF_H__
+
+#include "internal.h"
+#include "util.h"
+
+enum virNodeDevCapType {
+ /* Keep in sync with VIR_ENUM_IMPL in node_device_conf.c */
+ VIR_NODE_DEV_CAP_SYSTEM, /* System capability */
+ VIR_NODE_DEV_CAP_PCI_DEV, /* PCI device */
+ VIR_NODE_DEV_CAP_USB_DEV, /* USB device */
+ VIR_NODE_DEV_CAP_USB_INTERFACE, /* USB interface */
+ VIR_NODE_DEV_CAP_NET, /* Network device */
+ VIR_NODE_DEV_CAP_BLOCK, /* Block device */
+ VIR_NODE_DEV_CAP_SCSI_HOST, /* SCSI Host Bus Adapter */
+ VIR_NODE_DEV_CAP_SCSI, /* SCSI device */
+ VIR_NODE_DEV_CAP_STORAGE, /* Storage device */
+ VIR_NODE_DEV_CAP_LAST
+};
+
+enum virNodeDevNetCapType {
+ /* Keep in sync with VIR_ENUM_IMPL in node_device_conf.c */
+ VIR_NODE_DEV_CAP_NET_80203, /* 802.03 network device */
+ VIR_NODE_DEV_CAP_NET_80211, /* 802.11 network device */
+ VIR_NODE_DEV_CAP_NET_LAST
+};
+
+VIR_ENUM_DECL(virNodeDevCap);
+VIR_ENUM_DECL(virNodeDevNetCap);
+
+enum virNodeDevStorageCapFlags {
+ VIR_NODE_DEV_CAP_STORAGE_REMOVABLE = (1 << 0),
+ VIR_NODE_DEV_CAP_STORAGE_REMOVABLE_MEDIA_AVAILABLE = (1 << 1),
+ VIR_NODE_DEV_CAP_STORAGE_HOTPLUGGABLE = (1 << 2),
+};
+
+typedef struct _virNodeDevCapsDef virNodeDevCapsDef;
+typedef virNodeDevCapsDef *virNodeDevCapsDefPtr;
+struct _virNodeDevCapsDef {
+ enum virNodeDevCapType type;
+ union _virNodeDevCapData {
+ struct {
+ char *product_name;
+ struct {
+ char *vendor_name;
+ char *version;
+ char *serial;
+ unsigned char uuid[VIR_UUID_BUFLEN];
+ } hardware;
+ struct {
+ char *vendor_name;
+ char *version;
+ char *release_date;
+ } firmware;
+ } system;
+ struct {
+ unsigned domain;
+ unsigned bus;
+ unsigned slot;
+ unsigned function;
+ unsigned product;
+ unsigned vendor;
+ char *product_name;
+ char *vendor_name;
+ } pci_dev;
+ struct {
+ unsigned bus;
+ unsigned device;
+ unsigned product;
+ unsigned vendor;
+ char *product_name;
+ char *vendor_name;
+ } usb_dev;
+ struct {
+ unsigned number;
+ unsigned _class; /* "class" is reserved in C */
+ unsigned subclass;
+ unsigned protocol;
+ char *description;
+ } usb_if;
+ struct {
+ char *address;
+ char *interface;
+ enum virNodeDevNetCapType subtype; /* LAST -> no subtype */
+ } net;
+ struct {
+ char *device;
+ } block;
+ struct {
+ unsigned host;
+ } scsi_host;
+ struct {
+ unsigned host;
+ unsigned bus;
+ unsigned target;
+ unsigned lun;
+ char *type;
+ } scsi;
+ struct {
+ unsigned long long size;
+ unsigned long long removable_media_size;
+ char *bus;
+ char *drive_type;
+ char *model;
+ char *vendor;
+ unsigned flags; /* virNodeDevStorageCapFlags bits */
+ } storage;
+ } data;
+ virNodeDevCapsDefPtr next; /* next capability */
+};
+
+
+typedef struct _virNodeDeviceDef virNodeDeviceDef;
+typedef virNodeDeviceDef *virNodeDeviceDefPtr;
+struct _virNodeDeviceDef {
+ char *name; /* device name (unique on node) */
+ char *parent; /* optional parent device name */
+ virNodeDevCapsDefPtr caps; /* optional device capabilities */
+};
+
+
+typedef struct _virNodeDeviceObj virNodeDeviceObj;
+typedef virNodeDeviceObj *virNodeDeviceObjPtr;
+struct _virNodeDeviceObj {
+ virNodeDeviceDefPtr def; /* device definition */
+ void *privateData; /* driver-specific private data */
+ void (*privateFree)(void *data); /* destructor for private data */
+
+};
+
+typedef struct _virNodeDeviceObjList virNodeDeviceObjList;
+typedef virNodeDeviceObjList *virNodeDeviceObjListPtr;
+struct _virNodeDeviceObjList {
+ unsigned int count;
+ virNodeDeviceObjPtr *objs;
+};
+
+typedef struct _virDeviceMonitorState virDeviceMonitorState;
+typedef virDeviceMonitorState *virDeviceMonitorStatePtr;
+struct _virDeviceMonitorState {
+ virNodeDeviceObjList devs; /* currently-known devices */
+ void *privateData; /* driver-specific private data */
+};
+
+#define virNodeDeviceReportError(conn, code, fmt...) \
+ virReportErrorHelper(conn, VIR_FROM_NODEDEV, code, __FILE__, \
+ __FUNCTION__, __LINE__, fmt)
+
+virNodeDeviceObjPtr virNodeDeviceFindByName(const virNodeDeviceObjListPtr devs,
+ const char *name);
+
+virNodeDeviceObjPtr virNodeDeviceAssignDef(virConnectPtr conn,
+ virNodeDeviceObjListPtr devs,
+ const virNodeDeviceDefPtr def);
+
+void virNodeDeviceObjRemove(virNodeDeviceObjListPtr devs,
+ const virNodeDeviceObjPtr dev);
+
+char *virNodeDeviceDefFormat(virConnectPtr conn,
+ const virNodeDeviceDefPtr def);
+
+// TODO: virNodeDeviceDefParseString/File/Node for virNodeDeviceCreate
+
+void virNodeDeviceDefFree(virNodeDeviceDefPtr def);
+
+void virNodeDeviceObjFree(virNodeDeviceObjPtr dev);
+
+void virNodeDeviceObjListFree(virNodeDeviceObjListPtr devs);
+
+void virNodeDevCapsDefFree(virNodeDevCapsDefPtr caps);
+
+#endif /* __VIR_NODE_DEVICE_CONF_H__ */