From: Stefan Reiter <s.reiter@proxmox.com>
To: pve-devel@lists.proxmox.com
Subject: [pve-devel] [PATCH v2 qemu-server 3/7] add new 'boot' property format and introduce legacy conversion helpers
Date: Tue, 6 Oct 2020 15:32:14 +0200 [thread overview]
Message-ID: <20201006133218.25403-4-s.reiter@proxmox.com> (raw)
In-Reply-To: <20201006133218.25403-1-s.reiter@proxmox.com>
The format is unused in this commit, but will replace the current
string-based format of the 'boot' property. It is included since the
parameter of bootorder_from_legacy follows it.
Two helper methods are introduced:
* bootorder_from_legacy: Parses the legacy format into a hash closer to
what the new format represents
* get_default_bootdevices: Encapsulates the legacy default behaviour if
nothing is specified in the boot order
resolve_first_disk is simplified and gets a new $cdrom parameter to
control the behaviour of excluding CD-ROMs or instead searching for only
them.
Signed-off-by: Stefan Reiter <s.reiter@proxmox.com>
---
PVE/QemuServer.pm | 130 ++++++++++++++++++++++++++++++++++++++++
PVE/QemuServer/Drive.pm | 11 ++--
2 files changed, 135 insertions(+), 6 deletions(-)
diff --git a/PVE/QemuServer.pm b/PVE/QemuServer.pm
index bd59616..cfac03a 100644
--- a/PVE/QemuServer.pm
+++ b/PVE/QemuServer.pm
@@ -1091,6 +1091,68 @@ for (my $i = 0; $i < $MAX_USB_DEVICES; $i++) {
$confdesc->{"usb$i"} = $usbdesc;
}
+my $boot_fmt = {
+ legacy => {
+ optional => 1,
+ default_key => 1,
+ type => 'string',
+ description => "Boot on floppy (a), hard disk (c), CD-ROM (d), or network (n)."
+ . " Deprecated, use 'order=' instead.",
+ pattern => '[acdn]{1,4}',
+ format_description => "[acdn]{1,4}",
+
+ # note: this is also the fallback if boot: is not given at all
+ default => 'cdn',
+ },
+ order => {
+ optional => 1,
+ type => 'string',
+ format => 'pve-qm-bootdev-list',
+ format_description => "device[;device...]",
+ description => <<EODESC,
+The guest will attempt to boot from devices in the order they appear here.
+
+Disks, optical drives and passed-through storage USB devices will be directly
+booted from, NICs will load PXE, and PCIe devices will either behave like disks
+(e.g. NVMe) or load an option ROM (e.g. RAID controller, hardware NIC).
+
+Note that only devices in this list will be marked as bootable and thus loaded
+by the guest firmware (BIOS/UEFI). If you require multiple disks for booting
+(e.g. software-raid), you need to specify all of them here.
+
+Overrides the deprecated 'legacy=[acdn]*' value when given.
+EODESC
+ },
+};
+PVE::JSONSchema::register_format('pve-qm-boot', $boot_fmt);
+
+PVE::JSONSchema::register_format('pve-qm-bootdev', \&verify_bootdev);
+sub verify_bootdev {
+ my ($dev, $noerr) = @_;
+
+ return $dev if PVE::QemuServer::Drive::is_valid_drivename($dev) && $dev !~ m/^efidisk/;
+
+ my $check = sub {
+ my ($base) = @_;
+ return 0 if $dev !~ m/^$base\d+$/;
+ return 0 if !$confdesc->{$dev};
+ return 1;
+ };
+
+ return $dev if $check->("net");
+ return $dev if $check->("usb");
+ return $dev if $check->("hostpci");
+
+ return undef if $noerr;
+ die "invalid boot device '$dev'\n";
+}
+
+sub print_bootorder {
+ my ($devs) = @_;
+ my $data = { order => join(';', @$devs) };
+ return PVE::JSONSchema::print_property_string($data, $boot_fmt);
+}
+
my $kvm_api_version = 0;
sub kvm_version {
@@ -7152,6 +7214,74 @@ sub clear_reboot_request {
return $res;
}
+sub bootorder_from_legacy {
+ my ($conf, $bootcfg) = @_;
+
+ my $boot = $bootcfg->{legacy} || $boot_fmt->{legacy}->{default};
+ my $bootindex_hash = {};
+ my $i = 1;
+ foreach my $o (split(//, $boot)) {
+ $bootindex_hash->{$o} = $i*100;
+ $i++;
+ }
+
+ my $bootorder = {};
+
+ PVE::QemuConfig->foreach_volume($conf, sub {
+ my ($ds, $drive) = @_;
+
+ if (drive_is_cdrom ($drive, 1)) {
+ if ($bootindex_hash->{d}) {
+ $bootorder->{$ds} = $bootindex_hash->{d};
+ $bootindex_hash->{d} += 1;
+ }
+ } elsif ($bootindex_hash->{c}) {
+ $bootorder->{$ds} = $bootindex_hash->{c}
+ if $conf->{bootdisk} && $conf->{bootdisk} eq $ds;
+ $bootindex_hash->{c} += 1;
+ }
+ });
+
+ if ($bootindex_hash->{n}) {
+ for (my $i = 0; $i < $MAX_NETS; $i++) {
+ my $netname = "net$i";
+ next if !$conf->{$netname};
+ $bootorder->{$netname} = $bootindex_hash->{n};
+ $bootindex_hash->{n} += 1;
+ }
+ }
+
+ return $bootorder;
+}
+
+# Generate default device list for 'boot: order=' property. Matches legacy
+# default boot order, but with explicit device names. This is important, since
+# the fallback for when neither 'order' nor the old format is specified relies
+# on 'bootorder_from_legacy' above, and it would be confusing if this diverges.
+sub get_default_bootdevices {
+ my ($conf) = @_;
+
+ my @ret = ();
+
+ # harddisk
+ my $first = PVE::QemuServer::Drive::resolve_first_disk($conf, 0);
+ push @ret, $first if $first;
+
+ # cdrom
+ $first = PVE::QemuServer::Drive::resolve_first_disk($conf, 1);
+ push @ret, $first if $first;
+
+ # network
+ for (my $i = 0; $i < $MAX_NETS; $i++) {
+ my $netname = "net$i";
+ next if !$conf->{$netname};
+ push @ret, $netname;
+ last;
+ }
+
+ return \@ret;
+}
+
# bash completion helper
sub complete_backup_archives {
diff --git a/PVE/QemuServer/Drive.pm b/PVE/QemuServer/Drive.pm
index 91c33f8..b71fc93 100644
--- a/PVE/QemuServer/Drive.pm
+++ b/PVE/QemuServer/Drive.pm
@@ -584,16 +584,15 @@ sub is_volume_in_use {
}
sub resolve_first_disk {
- my $conf = shift;
+ my ($conf, $cdrom) = @_;
my @disks = valid_drive_names();
- my $firstdisk;
- foreach my $ds (reverse @disks) {
+ foreach my $ds (@disks) {
next if !$conf->{$ds};
my $disk = parse_drive($ds, $conf->{$ds});
- next if drive_is_cdrom($disk);
- $firstdisk = $ds;
+ next if drive_is_cdrom($disk) xor $cdrom;
+ return $ds;
}
- return $firstdisk;
+ return undef;
}
1;
--
2.20.1
next prev parent reply other threads:[~2020-10-06 13:33 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-10-06 13:32 [pve-devel] [PATCH v2 0/7] Improve boot device/order configuration Stefan Reiter
2020-10-06 13:32 ` [pve-devel] [PATCH v2 qemu-server 1/7] fix indentation Stefan Reiter
2020-10-06 13:32 ` [pve-devel] [PATCH v2 qemu-server 2/7] cfg2cmd: add test for legacy-style bootorder Stefan Reiter
2020-10-06 13:32 ` Stefan Reiter [this message]
2020-10-06 13:32 ` [pve-devel] [PATCH v2 qemu-server 4/7] fix #3010: add 'bootorder' parameter for better control of boot devices Stefan Reiter
2020-10-16 14:53 ` Thomas Lamprecht
2020-10-06 13:32 ` [pve-devel] [PATCH v2 qemu-server 5/7] api: add handling for new boot order format Stefan Reiter
2020-10-06 13:32 ` [pve-devel] [PATCH v2 qemu-server 6/7] cfg2cmd: add tests for new boot order property Stefan Reiter
2020-10-06 13:32 ` [pve-devel] [PATCH v2 manager 7/7] ui: improve boot order editor Stefan Reiter
2020-10-16 12:50 ` [pve-devel] applied-series: [PATCH v2 0/7] Improve boot device/order configuration Thomas Lamprecht
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20201006133218.25403-4-s.reiter@proxmox.com \
--to=s.reiter@proxmox.com \
--cc=pve-devel@lists.proxmox.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal