Support booting from hostdev devices

This commit is contained in:
Jiri Denemark 2011-02-03 13:06:21 +01:00
parent 2169472ab6
commit 83e335f9d2
4 changed files with 31 additions and 5 deletions

View File

@ -109,8 +109,9 @@
to consider. The <code>boot</code> element can be repeated multiple to consider. The <code>boot</code> element can be repeated multiple
times to setup a priority list of boot devices to try in turn. The times to setup a priority list of boot devices to try in turn. The
<code>boot</code> element cannot be used if per-device boot elements <code>boot</code> element cannot be used if per-device boot elements
are used (see <a href="#elementsDisks">disks</a> and are used (see <a href="#elementsDisks">disks</a>,
<a href="#elementsNICS">network interfaces</a> sections below. <a href="#elementsNICS">network interfaces</a>, and
<a href="#elementsUSB">USB and PCI devices</a> sections below).
<span class="since">Since 0.1.3, per-device boot since 0.8.8</span> <span class="since">Since 0.1.3, per-device boot since 0.8.8</span>
</dd> </dd>
<dt><code>bootmenu</code></dt> <dt><code>bootmenu</code></dt>
@ -929,6 +930,7 @@
&lt;vendor id='0x1234'/&gt; &lt;vendor id='0x1234'/&gt;
&lt;product id='0xbeef'/&gt; &lt;product id='0xbeef'/&gt;
&lt;/source&gt; &lt;/source&gt;
&lt;boot order='2'/&gt;
&lt;/hostdev&gt; &lt;/hostdev&gt;
&lt;/devices&gt; &lt;/devices&gt;
...</pre> ...</pre>
@ -942,6 +944,7 @@
&lt;source&gt; &lt;source&gt;
&lt;address bus='0x06' slot='0x02' function='0x0'/&gt; &lt;address bus='0x06' slot='0x02' function='0x0'/&gt;
&lt;/source&gt; &lt;/source&gt;
&lt;boot order='1'/&gt;
&lt;/hostdev&gt; &lt;/hostdev&gt;
&lt;/devices&gt; &lt;/devices&gt;
...</pre> ...</pre>
@ -964,6 +967,13 @@
<code>id</code> attribute that specifies the USB vendor and product id. <code>id</code> attribute that specifies the USB vendor and product id.
The ids can be given in decimal, hexadecimal (starting with 0x) or The ids can be given in decimal, hexadecimal (starting with 0x) or
octal (starting with 0) form.</dd> octal (starting with 0) form.</dd>
<dt><code>boot</code></dt>
<dd>Specifies that the device is bootable. The <code>order</code>
attribute determines the order in which devices will be tried during
boot sequence. The per-device <code>boot</code> elements cannot be
used together with general boot elements in
<a href="#elementsOSBIOS">BIOS bootloader</a> section.
<span class="since">Since 0.8.8</span></dd>
<dt><code>address</code></dt> <dt><code>address</code></dt>
<dd>The <code>address</code> element for USB devices has a <dd>The <code>address</code> element for USB devices has a
<code>bus</code> and <code>device</code> attribute to specify the <code>bus</code> and <code>device</code> attribute to specify the

View File

@ -1692,6 +1692,9 @@
</choice> </choice>
</element> </element>
</group> </group>
<optional>
<ref name="deviceBoot"/>
</optional>
<optional> <optional>
<ref name="address"/> <ref name="address"/>
</optional> </optional>

View File

@ -4247,7 +4247,9 @@ out:
static virDomainHostdevDefPtr static virDomainHostdevDefPtr
virDomainHostdevDefParseXML(const xmlNodePtr node, virDomainHostdevDefParseXML(const xmlNodePtr node,
int flags) { virBitmapPtr bootMap,
int flags)
{
xmlNodePtr cur; xmlNodePtr cur;
virDomainHostdevDefPtr def; virDomainHostdevDefPtr def;
@ -4308,6 +4310,10 @@ virDomainHostdevDefParseXML(const xmlNodePtr node,
/* address is parsed as part of virDomainDeviceInfoParseXML */ /* address is parsed as part of virDomainDeviceInfoParseXML */
} else if (xmlStrEqual(cur->name, BAD_CAST "alias")) { } else if (xmlStrEqual(cur->name, BAD_CAST "alias")) {
/* alias is parsed as part of virDomainDeviceInfoParseXML */ /* alias is parsed as part of virDomainDeviceInfoParseXML */
} else if (xmlStrEqual(cur->name, BAD_CAST "boot")) {
if (virDomainDeviceBootParseXML(cur, &def->bootIndex,
bootMap))
goto error;
} else { } else {
virDomainReportError(VIR_ERR_INTERNAL_ERROR, virDomainReportError(VIR_ERR_INTERNAL_ERROR,
_("unknown node %s"), cur->name); _("unknown node %s"), cur->name);
@ -4507,7 +4513,8 @@ virDomainDeviceDefPtr virDomainDeviceDefParse(virCapsPtr caps,
goto error; goto error;
} else if (xmlStrEqual(node->name, BAD_CAST "hostdev")) { } else if (xmlStrEqual(node->name, BAD_CAST "hostdev")) {
dev->type = VIR_DOMAIN_DEVICE_HOSTDEV; dev->type = VIR_DOMAIN_DEVICE_HOSTDEV;
if (!(dev->data.hostdev = virDomainHostdevDefParseXML(node, flags))) if (!(dev->data.hostdev = virDomainHostdevDefParseXML(node, NULL,
flags)))
goto error; goto error;
} else if (xmlStrEqual(node->name, BAD_CAST "controller")) { } else if (xmlStrEqual(node->name, BAD_CAST "controller")) {
dev->type = VIR_DOMAIN_DEVICE_CONTROLLER; dev->type = VIR_DOMAIN_DEVICE_CONTROLLER;
@ -4767,7 +4774,8 @@ virDomainDefParseBootXML(xmlXPathContextPtr ctxt,
unsigned long deviceBoot; unsigned long deviceBoot;
if (virXPathULong("count(./devices/disk[boot]" if (virXPathULong("count(./devices/disk[boot]"
"|./devices/interface[boot])", ctxt, &deviceBoot) < 0) { "|./devices/interface[boot]"
"|./devices/hostdev[boot])", ctxt, &deviceBoot) < 0) {
virDomainReportError(VIR_ERR_INTERNAL_ERROR, "%s", virDomainReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("cannot count boot devices")); _("cannot count boot devices"));
goto cleanup; goto cleanup;
@ -5506,6 +5514,7 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps,
goto no_memory; goto no_memory;
for (i = 0 ; i < n ; i++) { for (i = 0 ; i < n ; i++) {
virDomainHostdevDefPtr hostdev = virDomainHostdevDefParseXML(nodes[i], virDomainHostdevDefPtr hostdev = virDomainHostdevDefParseXML(nodes[i],
bootMap,
flags); flags);
if (!hostdev) if (!hostdev)
goto error; goto error;
@ -7280,6 +7289,9 @@ virDomainHostdevDefFormat(virBufferPtr buf,
virBufferAddLit(buf, " </source>\n"); virBufferAddLit(buf, " </source>\n");
if (def->bootIndex)
virBufferVSprintf(buf, " <boot order='%d'/>\n", def->bootIndex);
if (virDomainDeviceInfoFormat(buf, &def->info, flags) < 0) if (virDomainDeviceInfoFormat(buf, &def->info, flags) < 0)
return -1; return -1;

View File

@ -678,6 +678,7 @@ struct _virDomainHostdevDef {
} caps; } caps;
} source; } source;
char* target; char* target;
int bootIndex;
virDomainDeviceInfo info; /* Guest address */ virDomainDeviceInfo info; /* Guest address */
}; };