mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-12 15:52:55 +00:00
conf: Allow for non-contiguous device boot orders
This patch adds the ability to configure non-contiguous boot orders on boot devices. This allows unplugging devices that have boot order specified without breaking migration. The new code now uses a slightly less memory efficient approach to store the boot order fields in a hashtable instead of a bitmap.
This commit is contained in:
parent
e7b0382945
commit
039a3283fc
@ -3119,7 +3119,7 @@ cleanup:
|
|||||||
static int
|
static int
|
||||||
virDomainDeviceBootParseXML(xmlNodePtr node,
|
virDomainDeviceBootParseXML(xmlNodePtr node,
|
||||||
int *bootIndex,
|
int *bootIndex,
|
||||||
virBitmapPtr bootMap)
|
virHashTablePtr bootHash)
|
||||||
{
|
{
|
||||||
char *order;
|
char *order;
|
||||||
int boot;
|
int boot;
|
||||||
@ -3138,18 +3138,16 @@ virDomainDeviceBootParseXML(xmlNodePtr node,
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bootMap) {
|
if (bootHash) {
|
||||||
bool set;
|
if (virHashLookup(bootHash, order)) {
|
||||||
if (virBitmapGetBit(bootMap, boot - 1, &set) < 0) {
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
_("boot order '%s' used for more than one device"),
|
||||||
_("boot orders have to be contiguous and starting from 1"));
|
order);
|
||||||
goto cleanup;
|
|
||||||
} else if (set) {
|
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
||||||
_("boot order %d used for more than one device"), boot);
|
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
ignore_value(virBitmapSetBit(bootMap, boot - 1));
|
|
||||||
|
if (virHashAddEntry(bootHash, order, (void *) 1) < 0)
|
||||||
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
*bootIndex = boot;
|
*bootIndex = boot;
|
||||||
@ -3165,7 +3163,7 @@ cleanup:
|
|||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
virDomainDeviceInfoParseXML(xmlNodePtr node,
|
virDomainDeviceInfoParseXML(xmlNodePtr node,
|
||||||
virBitmapPtr bootMap,
|
virHashTablePtr bootHash,
|
||||||
virDomainDeviceInfoPtr info,
|
virDomainDeviceInfoPtr info,
|
||||||
unsigned int flags)
|
unsigned int flags)
|
||||||
{
|
{
|
||||||
@ -3216,7 +3214,7 @@ virDomainDeviceInfoParseXML(xmlNodePtr node,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (boot) {
|
if (boot) {
|
||||||
if (virDomainDeviceBootParseXML(boot, &info->bootIndex, bootMap))
|
if (virDomainDeviceBootParseXML(boot, &info->bootIndex, bootHash))
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4237,7 +4235,7 @@ static virDomainDiskDefPtr
|
|||||||
virDomainDiskDefParseXML(virDomainXMLOptionPtr xmlopt,
|
virDomainDiskDefParseXML(virDomainXMLOptionPtr xmlopt,
|
||||||
xmlNodePtr node,
|
xmlNodePtr node,
|
||||||
xmlXPathContextPtr ctxt,
|
xmlXPathContextPtr ctxt,
|
||||||
virBitmapPtr bootMap,
|
virHashTablePtr bootHash,
|
||||||
virSecurityLabelDefPtr* vmSeclabels,
|
virSecurityLabelDefPtr* vmSeclabels,
|
||||||
int nvmSeclabels,
|
int nvmSeclabels,
|
||||||
unsigned int flags)
|
unsigned int flags)
|
||||||
@ -4968,7 +4966,7 @@ virDomainDiskDefParseXML(virDomainXMLOptionPtr xmlopt,
|
|||||||
}
|
}
|
||||||
def->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
|
def->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
|
||||||
} else {
|
} else {
|
||||||
if (virDomainDeviceInfoParseXML(node, bootMap, &def->info,
|
if (virDomainDeviceInfoParseXML(node, bootHash, &def->info,
|
||||||
flags | VIR_DOMAIN_XML_INTERNAL_ALLOW_BOOT) < 0)
|
flags | VIR_DOMAIN_XML_INTERNAL_ALLOW_BOOT) < 0)
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
@ -5631,7 +5629,7 @@ static virDomainNetDefPtr
|
|||||||
virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
|
virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
|
||||||
xmlNodePtr node,
|
xmlNodePtr node,
|
||||||
xmlXPathContextPtr ctxt,
|
xmlXPathContextPtr ctxt,
|
||||||
virBitmapPtr bootMap,
|
virHashTablePtr bootHash,
|
||||||
unsigned int flags)
|
unsigned int flags)
|
||||||
{
|
{
|
||||||
virDomainNetDefPtr def;
|
virDomainNetDefPtr def;
|
||||||
@ -5826,7 +5824,7 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
|
|||||||
}
|
}
|
||||||
def->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
|
def->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
|
||||||
} else {
|
} else {
|
||||||
if (virDomainDeviceInfoParseXML(node, bootMap, &def->info,
|
if (virDomainDeviceInfoParseXML(node, bootHash, &def->info,
|
||||||
flags | VIR_DOMAIN_XML_INTERNAL_ALLOW_BOOT
|
flags | VIR_DOMAIN_XML_INTERNAL_ALLOW_BOOT
|
||||||
| VIR_DOMAIN_XML_INTERNAL_ALLOW_ROM) < 0)
|
| VIR_DOMAIN_XML_INTERNAL_ALLOW_ROM) < 0)
|
||||||
goto error;
|
goto error;
|
||||||
@ -8278,7 +8276,7 @@ error:
|
|||||||
static virDomainHostdevDefPtr
|
static virDomainHostdevDefPtr
|
||||||
virDomainHostdevDefParseXML(const xmlNodePtr node,
|
virDomainHostdevDefParseXML(const xmlNodePtr node,
|
||||||
xmlXPathContextPtr ctxt,
|
xmlXPathContextPtr ctxt,
|
||||||
virBitmapPtr bootMap,
|
virHashTablePtr bootHash,
|
||||||
unsigned int flags)
|
unsigned int flags)
|
||||||
{
|
{
|
||||||
virDomainHostdevDefPtr def;
|
virDomainHostdevDefPtr def;
|
||||||
@ -8319,7 +8317,7 @@ virDomainHostdevDefParseXML(const xmlNodePtr node,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (def->info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) {
|
if (def->info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) {
|
||||||
if (virDomainDeviceInfoParseXML(node, bootMap, def->info,
|
if (virDomainDeviceInfoParseXML(node, bootHash, def->info,
|
||||||
flags | VIR_DOMAIN_XML_INTERNAL_ALLOW_BOOT
|
flags | VIR_DOMAIN_XML_INTERNAL_ALLOW_BOOT
|
||||||
| VIR_DOMAIN_XML_INTERNAL_ALLOW_ROM) < 0)
|
| VIR_DOMAIN_XML_INTERNAL_ALLOW_ROM) < 0)
|
||||||
goto error;
|
goto error;
|
||||||
@ -8353,7 +8351,7 @@ error:
|
|||||||
|
|
||||||
static virDomainRedirdevDefPtr
|
static virDomainRedirdevDefPtr
|
||||||
virDomainRedirdevDefParseXML(const xmlNodePtr node,
|
virDomainRedirdevDefParseXML(const xmlNodePtr node,
|
||||||
virBitmapPtr bootMap,
|
virHashTablePtr bootHash,
|
||||||
unsigned int flags)
|
unsigned int flags)
|
||||||
{
|
{
|
||||||
xmlNodePtr cur;
|
xmlNodePtr cur;
|
||||||
@ -8403,7 +8401,7 @@ virDomainRedirdevDefParseXML(const xmlNodePtr node,
|
|||||||
def->source.chr.data.spicevmc = VIR_DOMAIN_CHR_SPICEVMC_USBREDIR;
|
def->source.chr.data.spicevmc = VIR_DOMAIN_CHR_SPICEVMC_USBREDIR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (virDomainDeviceInfoParseXML(node, bootMap, &def->info,
|
if (virDomainDeviceInfoParseXML(node, bootHash, &def->info,
|
||||||
flags | VIR_DOMAIN_XML_INTERNAL_ALLOW_BOOT) < 0)
|
flags | VIR_DOMAIN_XML_INTERNAL_ALLOW_BOOT) < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
@ -9405,8 +9403,7 @@ virDomainDefGetDefaultEmulator(virDomainDefPtr def,
|
|||||||
|
|
||||||
static int
|
static int
|
||||||
virDomainDefParseBootXML(xmlXPathContextPtr ctxt,
|
virDomainDefParseBootXML(xmlXPathContextPtr ctxt,
|
||||||
virDomainDefPtr def,
|
virDomainDefPtr def)
|
||||||
unsigned long *bootCount)
|
|
||||||
{
|
{
|
||||||
xmlNodePtr *nodes = NULL;
|
xmlNodePtr *nodes = NULL;
|
||||||
int i, n;
|
int i, n;
|
||||||
@ -9503,7 +9500,6 @@ virDomainDefParseBootXML(xmlXPathContextPtr ctxt,
|
|||||||
def->os.bios.rt_set = true;
|
def->os.bios.rt_set = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
*bootCount = deviceBoot;
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
@ -9701,8 +9697,7 @@ virDomainDefParseXML(xmlDocPtr xml,
|
|||||||
virDomainDefPtr def;
|
virDomainDefPtr def;
|
||||||
unsigned long count;
|
unsigned long count;
|
||||||
bool uuid_generated = false;
|
bool uuid_generated = false;
|
||||||
virBitmapPtr bootMap = NULL;
|
virHashTablePtr bootHash = NULL;
|
||||||
unsigned long bootMapSize = 0;
|
|
||||||
xmlNodePtr cur;
|
xmlNodePtr cur;
|
||||||
bool usb_none = false;
|
bool usb_none = false;
|
||||||
bool usb_other = false;
|
bool usb_other = false;
|
||||||
@ -10584,10 +10579,10 @@ virDomainDefParseXML(xmlDocPtr xml,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (STREQ(def->os.type, "hvm")) {
|
if (STREQ(def->os.type, "hvm")) {
|
||||||
if (virDomainDefParseBootXML(ctxt, def, &bootMapSize) < 0)
|
if (virDomainDefParseBootXML(ctxt, def) < 0)
|
||||||
|
goto error;
|
||||||
|
if (!(bootHash = virHashCreate(5, NULL)))
|
||||||
goto error;
|
goto error;
|
||||||
if (bootMapSize && !(bootMap = virBitmapNew(bootMapSize)))
|
|
||||||
goto no_memory;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def->emulator = virXPathString("string(./devices/emulator[1])", ctxt);
|
def->emulator = virXPathString("string(./devices/emulator[1])", ctxt);
|
||||||
@ -10603,7 +10598,7 @@ virDomainDefParseXML(xmlDocPtr xml,
|
|||||||
virDomainDiskDefPtr disk = virDomainDiskDefParseXML(xmlopt,
|
virDomainDiskDefPtr disk = virDomainDiskDefParseXML(xmlopt,
|
||||||
nodes[i],
|
nodes[i],
|
||||||
ctxt,
|
ctxt,
|
||||||
bootMap,
|
bootHash,
|
||||||
def->seclabels,
|
def->seclabels,
|
||||||
def->nseclabels,
|
def->nseclabels,
|
||||||
flags);
|
flags);
|
||||||
@ -10703,7 +10698,7 @@ virDomainDefParseXML(xmlDocPtr xml,
|
|||||||
virDomainNetDefPtr net = virDomainNetDefParseXML(xmlopt,
|
virDomainNetDefPtr net = virDomainNetDefParseXML(xmlopt,
|
||||||
nodes[i],
|
nodes[i],
|
||||||
ctxt,
|
ctxt,
|
||||||
bootMap,
|
bootHash,
|
||||||
flags);
|
flags);
|
||||||
if (!net)
|
if (!net)
|
||||||
goto error;
|
goto error;
|
||||||
@ -11020,7 +11015,7 @@ virDomainDefParseXML(xmlDocPtr xml,
|
|||||||
for (i = 0 ; i < n ; i++) {
|
for (i = 0 ; i < n ; i++) {
|
||||||
virDomainHostdevDefPtr hostdev;
|
virDomainHostdevDefPtr hostdev;
|
||||||
|
|
||||||
hostdev = virDomainHostdevDefParseXML(nodes[i], ctxt, bootMap, flags);
|
hostdev = virDomainHostdevDefParseXML(nodes[i], ctxt, bootHash, flags);
|
||||||
if (!hostdev)
|
if (!hostdev)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
@ -11136,7 +11131,7 @@ virDomainDefParseXML(xmlDocPtr xml,
|
|||||||
goto no_memory;
|
goto no_memory;
|
||||||
for (i = 0 ; i < n ; i++) {
|
for (i = 0 ; i < n ; i++) {
|
||||||
virDomainRedirdevDefPtr redirdev = virDomainRedirdevDefParseXML(nodes[i],
|
virDomainRedirdevDefPtr redirdev = virDomainRedirdevDefParseXML(nodes[i],
|
||||||
bootMap,
|
bootHash,
|
||||||
flags);
|
flags);
|
||||||
if (!redirdev)
|
if (!redirdev)
|
||||||
goto error;
|
goto error;
|
||||||
@ -11257,7 +11252,7 @@ virDomainDefParseXML(xmlDocPtr xml,
|
|||||||
if (virDomainDefPostParse(def, caps, xmlopt) < 0)
|
if (virDomainDefPostParse(def, caps, xmlopt) < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
virBitmapFree(bootMap);
|
virHashFree(bootHash);
|
||||||
|
|
||||||
return def;
|
return def;
|
||||||
|
|
||||||
@ -11266,7 +11261,7 @@ no_memory:
|
|||||||
error:
|
error:
|
||||||
VIR_FREE(tmp);
|
VIR_FREE(tmp);
|
||||||
VIR_FREE(nodes);
|
VIR_FREE(nodes);
|
||||||
virBitmapFree(bootMap);
|
virHashFree(bootHash);
|
||||||
virDomainDefFree(def);
|
virDomainDefFree(def);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user