On September 2, 2019 4:27 pm, Stefan Reiter wrote: > * query_understood_cpu_flags returns all flags that QEMU/KVM knows about > * query_supported_cpu_flags returns all flags that QEMU/KVM can use on > this particular host. > > To get supported flags, a temporary VM is started with QEMU, so we can > issue the "query-cpu-model-expansion" QMP command. This is how libvirt > queries supported flags for its "host-passthrough" CPU type. > > query_supported_cpu_flags is thus rather slow and shouldn't be called > unnecessarily. > > Signed-off-by: Stefan Reiter <s.rei...@proxmox.com> > --- > > Changes from RFC: > > * Clearer regexes > * Use existing QMP infrastructure > * Add locking for temporary VM start > * Add comments > > > PVE/QemuServer.pm | 84 +++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 84 insertions(+) > > diff --git a/PVE/QemuServer.pm b/PVE/QemuServer.pm > index 8c519b5..97fa955 100644 > --- a/PVE/QemuServer.pm > +++ b/PVE/QemuServer.pm > @@ -3500,6 +3500,90 @@ sub get_command_for_arch($) { > return $cmd; > } > > +# The format of the flags returned here uses dashes '-' as seperators,
nit: s/seperator/separator/a > +# this is neither the default for 'query_supported_cpu_flags' below, nor for > +# /proc/cpuinfo. > +# > +# To compare (or array_intersect) flags, it's a good idea to convert them all > +# to a common format first (e.g. map s/\.|-/_/g). > +sub query_understood_cpu_flags { not used anywhere in this series? also, confusingly, this returns less values then the other helper (maybe because of some aliases?), and it's not a strict subset :-/ I guess this is in preparation of exposing it via the API? some sort of comment how _understood and _supported interact/are supposed to interact would be nice. either as comment or part of the commit message > + my $flags = []; > + my $flag_section = 0; > + > + run_command( > + [get_command_for_arch('x86_64'), '-cpu', 'help'], why not get_host_arch()? > + noerr => 1, > + quiet => 1, > + outfunc => sub { > + my ($line) = @_; > + > + if ($flag_section) { > + return if $line =~ m/^\s*$/; > + $line =~ s/^\s*|\s*$//g; > + push @$flags, split(/\s+/, $line); > + } elsif ($line =~ m/^\s*Recognized CPUID flags:\s*$/) { > + $flag_section = 1; > + } > + } > + ); > + > + return $flags; > +} > + > +# This function needs to start a temporary VM and is therefore rather > expensive. > +# If you need the value returned from this, you can get it much cheaper from > +# pvestatd using PVE::Cluster::get_node_kv('cpuflags'). s/pvestatd/pmxcfs/ pvestatd is just the one putting it there ;) > +# > +# See also note to query_understood_cpu_flags above. > +sub query_supported_cpu_flags { > + my $flags = []; > + > + my $vmid = -1; > + my $pidfile = pidfile_name($vmid); > + > + PVE::QemuConfig->lock_config($vmid, sub { > + # We start a temporary (frozen) VM with vmid -1 to allow us to send a > QMP command > + my $rc = run_command([ > + get_command_for_arch('x86_64'), again, why not get_host_arch()? > + '-cpu', 'kvm64', > + '-display', 'none', > + '-chardev', > "socket,id=qmp,path=/var/run/qemu-server/$vmid.qmp,server,nowait", > + '-mon', 'chardev=qmp,mode=control', > + '-pidfile', $pidfile, > + '-S', '-daemonize' > + ], noerr => 1, quiet => 1); > + return if $rc; > + > + my $cmd_result = vm_mon_cmd_nocheck( > + $vmid, > + 'query-cpu-model-expansion', > + type => 'full', > + model => { name => 'host' } > + ); > + > + my $props = $cmd_result->{model}->{props}; > + if (%$props) { > + foreach my $prop (keys %$props) { > + push @$flags, $prop if "$props->{$prop}" eq '1'; > + } > + } > + > + # force stop with 10 sec timeout and 'nocheck' > + vm_stop(undef, $vmid, 1, 1, 10, 0, 1); > + }); > + > + # QEMU returns some flags multiple times, with '_', '.' or '-' as > seperator > + # (e.g. lahf_lm and lahf-lm; sse4.2, sse4-2 and sse4_2; ...). > + # We only keep those with underscores, since they match the ones from > + # /proc/cpuinfo (they do the same thing, but we get rid of duplicates). > + @$flags = grep { > + my $replaced = (my $underscore = $_) =~ s/\.|-/_/g; > + !($replaced && grep { $_ eq $underscore } @$flags) > + } @$flags; > + > + return $flags; > +} > + > sub get_cpu_options { > my ($conf, $arch, $kvm, $machine_type, $kvm_off, $kvmver, $winversion, > $gpu_passthrough) = @_; > > -- > 2.20.1 > > > _______________________________________________ > pve-devel mailing list > pve-devel@pve.proxmox.com > https://pve.proxmox.com/cgi-bin/mailman/listinfo/pve-devel > > _______________________________________________ pve-devel mailing list pve-devel@pve.proxmox.com https://pve.proxmox.com/cgi-bin/mailman/listinfo/pve-devel