mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 05:35:25 +00:00
nodedev: add <devnode> paths
Add new <devnode> top-level <device> element, that list the associated /dev files. Distinguish the main /dev name from symlinks with a 'type' attribute of value 'dev' or 'symlink'. Update a test to check XML schema, and actually add it to the test list since it was missing. Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
This commit is contained in:
parent
7f64435307
commit
0809508ed2
@ -37,6 +37,12 @@
|
||||
<dd>If this element is present, it names the parent device (that
|
||||
is, a controller to which this node belongs).
|
||||
</dd>
|
||||
<dt><code>devnode</code></dt>
|
||||
<dd>This node appears for each associated <code>/dev</code>
|
||||
special file. A mandatory attribute <code>type</code> specify
|
||||
the kind of file path, which may be either <code>dev</code> for
|
||||
the main name, or <code>link</code> for additional symlinks.
|
||||
</dd>
|
||||
<dt><code>capability</code></dt>
|
||||
<dd>This node appears for each capability that libvirt
|
||||
associates with a node. A mandatory
|
||||
|
@ -15,6 +15,22 @@
|
||||
<optional>
|
||||
<element name="path"><text/></element>
|
||||
</optional>
|
||||
<optional>
|
||||
<element name="devnode">
|
||||
<attribute name='type'>
|
||||
<value>dev</value>
|
||||
</attribute>
|
||||
<text/>
|
||||
</element>
|
||||
</optional>
|
||||
<zeroOrMore>
|
||||
<element name="devnode">
|
||||
<attribute name='type'>
|
||||
<value>link</value>
|
||||
</attribute>
|
||||
<text/>
|
||||
</element>
|
||||
</zeroOrMore>
|
||||
<optional>
|
||||
<ref name="parent"/>
|
||||
</optional>
|
||||
|
@ -40,6 +40,10 @@
|
||||
|
||||
#define VIR_FROM_THIS VIR_FROM_NODEDEV
|
||||
|
||||
VIR_ENUM_IMPL(virNodeDevDevnode, VIR_NODE_DEV_DEVNODE_LAST,
|
||||
"dev",
|
||||
"link")
|
||||
|
||||
VIR_ENUM_IMPL(virNodeDevCap, VIR_NODE_DEV_CAP_LAST,
|
||||
"system",
|
||||
"pci",
|
||||
@ -252,6 +256,8 @@ void virNodeDeviceDefFree(virNodeDeviceDefPtr def)
|
||||
VIR_FREE(def->driver);
|
||||
VIR_FREE(def->sysfs_path);
|
||||
VIR_FREE(def->parent_sysfs_path);
|
||||
VIR_FREE(def->devnode);
|
||||
virStringListFree(def->devlinks);
|
||||
|
||||
caps = def->caps;
|
||||
while (caps) {
|
||||
@ -387,6 +393,14 @@ char *virNodeDeviceDefFormat(const virNodeDeviceDef *def)
|
||||
virBufferAdjustIndent(&buf, 2);
|
||||
virBufferEscapeString(&buf, "<name>%s</name>\n", def->name);
|
||||
virBufferEscapeString(&buf, "<path>%s</path>\n", def->sysfs_path);
|
||||
if (def->devnode)
|
||||
virBufferEscapeString(&buf, "<devnode type='dev'>%s</devnode>\n",
|
||||
def->devnode);
|
||||
if (def->devlinks) {
|
||||
for (i = 0; def->devlinks[i]; i++)
|
||||
virBufferEscapeString(&buf, "<devnode type='link'>%s</devnode>\n",
|
||||
def->devlinks[i]);
|
||||
}
|
||||
if (def->parent)
|
||||
virBufferEscapeString(&buf, "<parent>%s</parent>\n", def->parent);
|
||||
if (def->driver) {
|
||||
@ -1703,7 +1717,7 @@ virNodeDeviceDefParseXML(xmlXPathContextPtr ctxt,
|
||||
virNodeDeviceDefPtr def;
|
||||
virNodeDevCapsDefPtr *next_cap;
|
||||
xmlNodePtr *nodes;
|
||||
int n;
|
||||
int n, m;
|
||||
size_t i;
|
||||
|
||||
if (VIR_ALLOC(def) < 0)
|
||||
@ -1722,6 +1736,44 @@ virNodeDeviceDefParseXML(xmlXPathContextPtr ctxt,
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Parse devnodes */
|
||||
nodes = NULL;
|
||||
if ((n = virXPathNodeSet("./devnode", ctxt, &nodes)) < 0)
|
||||
goto error;
|
||||
|
||||
if (VIR_ALLOC_N(def->devlinks, n + 1) < 0)
|
||||
goto error;
|
||||
|
||||
for (i = 0, m = 0; i < n; i++) {
|
||||
xmlNodePtr node = nodes[i];
|
||||
char *tmp = virXMLPropString(node, "type");
|
||||
virNodeDevDevnodeType type;
|
||||
|
||||
if (!tmp) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
"%s", _("missing devnode type"));
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ((type = virNodeDevDevnodeTypeFromString(tmp)) < 0) {
|
||||
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
||||
_("unknown devnode type '%s'"), tmp);
|
||||
VIR_FREE(tmp);
|
||||
goto error;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case VIR_NODE_DEV_DEVNODE_DEV:
|
||||
def->devnode = (char*)xmlNodeGetContent(node);
|
||||
break;
|
||||
case VIR_NODE_DEV_DEVNODE_LINK:
|
||||
def->devlinks[m++] = (char*)xmlNodeGetContent(node);
|
||||
break;
|
||||
case VIR_NODE_DEV_DEVNODE_LAST:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Extract device parent, if any */
|
||||
def->parent = virXPathString("string(./parent[1])", ctxt);
|
||||
def->parent_wwnn = virXPathString("string(./parent[1]/@wwnn)", ctxt);
|
||||
|
@ -38,6 +38,16 @@
|
||||
# define CREATE_DEVICE 1
|
||||
# define EXISTING_DEVICE 0
|
||||
|
||||
typedef enum {
|
||||
/* Keep in sync with VIR_ENUM_IMPL in node_device_conf.c */
|
||||
VIR_NODE_DEV_DEVNODE_DEV,
|
||||
VIR_NODE_DEV_DEVNODE_LINK,
|
||||
|
||||
VIR_NODE_DEV_DEVNODE_LAST
|
||||
} virNodeDevDevnodeType;
|
||||
|
||||
VIR_ENUM_DECL(virNodeDevDevnode)
|
||||
|
||||
typedef enum {
|
||||
/* Keep in sync with VIR_ENUM_IMPL in node_device_conf.c */
|
||||
VIR_NODE_DEV_CAP_SYSTEM, /* System capability */
|
||||
@ -204,6 +214,8 @@ struct _virNodeDeviceDef {
|
||||
char *parent_wwpn; /* optional parent wwpn */
|
||||
char *parent_fabric_wwn; /* optional parent fabric_wwn */
|
||||
char *driver; /* optional driver name */
|
||||
char *devnode; /* /dev path */
|
||||
char **devlinks; /* /dev links */
|
||||
virNodeDevCapsDefPtr caps; /* optional device capabilities */
|
||||
};
|
||||
|
||||
|
@ -917,6 +917,34 @@ udevProcessSCSIGeneric(struct udev_device *dev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
udevGetDeviceNodes(struct udev_device *device,
|
||||
virNodeDeviceDefPtr def)
|
||||
{
|
||||
const char *devnode = NULL;
|
||||
struct udev_list_entry *list_entry = NULL;
|
||||
int n = 0;
|
||||
|
||||
devnode = udev_device_get_devnode(device);
|
||||
|
||||
if (VIR_STRDUP(def->devnode, devnode) < 0)
|
||||
return -1;
|
||||
|
||||
udev_list_entry_foreach(list_entry, udev_device_get_devlinks_list_entry(device))
|
||||
n++;
|
||||
|
||||
if (VIR_ALLOC_N(def->devlinks, n + 1) < 0)
|
||||
return -1;
|
||||
|
||||
n = 0;
|
||||
udev_list_entry_foreach(list_entry, udev_device_get_devlinks_list_entry(device)) {
|
||||
if (VIR_STRDUP(def->devlinks[n++], udev_list_entry_get_name(list_entry)) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
udevGetDeviceType(struct udev_device *device,
|
||||
virNodeDevCapType *type)
|
||||
@ -1125,6 +1153,9 @@ static int udevAddOneDevice(struct udev_device *device)
|
||||
if (udevGetDeviceType(device, &def->caps->data.type) != 0)
|
||||
goto cleanup;
|
||||
|
||||
if (udevGetDeviceNodes(device, def) != 0)
|
||||
goto cleanup;
|
||||
|
||||
if (udevGetDeviceDetails(device, def) != 0)
|
||||
goto cleanup;
|
||||
|
||||
|
@ -1,5 +1,9 @@
|
||||
<device>
|
||||
<name>storage_serial_3600c0ff000d7a2a5d463ff4902000000</name>
|
||||
<devnode type='dev'>/dev/sdb</devnode>
|
||||
<devnode type='link'>/dev/disk/by-id/usb-SanDisk_Ultra_Fit_4C530001051009112405-0:0</devnode>
|
||||
<devnode type='link'>/dev/disk/by-path/pci-0000:00:14.0-usb-0:1:1.0-scsi-0:0:0:0</devnode>
|
||||
<devnode type='link'>/dev/disk/by-uuid/661A1A460111DA18</devnode>
|
||||
<parent>pci_10df_fe00_scsi_host_scsi_device_lun8</parent>
|
||||
<capability type='storage'>
|
||||
<block>/dev/sdj</block>
|
||||
|
@ -87,6 +87,7 @@ mymain(void)
|
||||
DO_TEST("pci_8086_27c5_scsi_host_scsi_host");
|
||||
DO_TEST("pci_8086_27c5_scsi_host");
|
||||
DO_TEST("storage_serial_SATA_HTS721010G9SA00_MPCZ12Y0GNGWSE");
|
||||
DO_TEST("storage_serial_3600c0ff000d7a2a5d463ff4902000000");
|
||||
DO_TEST("usb_device_1d6b_1_0000_00_1d_0_if0");
|
||||
DO_TEST("usb_device_1d6b_1_0000_00_1d_0");
|
||||
DO_TEST("pci_8086_4238_pcie_wireless");
|
||||
|
Loading…
Reference in New Issue
Block a user