On Sun, Dec 13, 2015 at 06:41:21AM +0300, Roman Bogorodskiy wrote: > Make bhyveload respect boot order as specified by os.boot section of the > domain XML or by "boot order" for specific devices. As bhyve does not > support a real boot order specification right now, it's just about > choosing a single device to boot from. So if bhyve only lets you specify a single device to boot from, then we should report an error to the user if they provide more than one <boot> element in the XML. > +static virDomainDiskDefPtr > +virBhyveGetBootDisk(virConnectPtr conn, virDomainDefPtr def) > +{ > + size_t i; > + virDomainDiskDefPtr match = NULL; > + int best_index = INT_MAX; > + int boot_cdrom = 0, boot_disk = 0; > + > + if (def->ndisks == 0) > + return NULL; > + > + for (i = 0; i < def->os.nBootDevs; i++) { > + switch (def->os.bootDevs[i]) { > + case VIR_DOMAIN_BOOT_CDROM: > + boot_cdrom = i; > + break; > + case VIR_DOMAIN_BOOT_DISK: > + boot_disk = i; > + break; > + } > + } IOW instead of this, we should just do int boot_dev = -1; if (def->ndisks > 1) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("Only one boot device is supported"); return NULL; } switch (def->os.bootDevs[0]) { case VIR_DOMAIN_BOOT_DISK: boot_dev = VIR_DOMAIN_DISK_DEVICE_DISK; break; case VIR_DOMAIN_BOOT_CDROM: boot_dev = VIR_DOMAIN_DISK_DEVICE_CDROM; break; default: virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Cannot boot from device %s"), virDOmainBootDeviceTypeToString(def->os.bootDevs[0])); return NULL; } Now look for the first disk where disk->device == boot_dev and use that to boot from. Note however that '<boot ...>' only takes effect if you have *not* got any boot index values specified on devices. ie they are considered mutually exclusive. http://libvirt.org/formatdomain.html#elementsOSBIOS "The boot element and per-device boot elements are mutually exclusive." So now in this loop: > + for (i = 0; i < def->ndisks; i++) { > + int bootIndex; > + if (!virBhyveUsableDisk(conn, def->disks[i])) > + continue; > + > + bootIndex = def->disks[i]->info.bootIndex; > + if (def->disks[i]->device == VIR_DOMAIN_DISK_DEVICE_CDROM) > + bootIndex += boot_cdrom; > + else if (def->disks[i]->device == VIR_DOMAIN_DISK_DEVICE_DISK) > + bootIndex += boot_disk; > + > + if (bootIndex < best_index) { > + best_index = bootIndex; > + match = def->disks[i]; > + } > + } If 'boot_dev != -1' then you should report an error if you see any 'bootIndex != -1'. If 'boot_dev == -1', then you should have exactly one device with a bootIndex != -1. If you see multiple devices with a boot index set, you should again report an VIR_ERR_CONFIG_UNSUPPORTED to inform the user that their config cannot be honoured. > + > + return match; > +} > + > virCommandPtr > virBhyveProcessBuildLoadCmd(virConnectPtr conn, virDomainDefPtr def, > const char *devmap_file, char **devicesmap_out) > @@ -535,10 +577,11 @@ virBhyveProcessBuildLoadCmd(virConnectPtr conn, virDomainDefPtr def, > } > > if (def->os.bootloader == NULL) { > - disk = def->disks[0]; > + disk = virBhyveGetBootDisk(conn, def); > > - if (!virBhyveUsableDisk(conn, disk)) > - return NULL; > + if (disk == NULL) > + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", > + _("no bootable disks found")); Push that error message into virBhyveGetBootDisk as there are multiple different errors to report now. Regards, Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list