From: Filip Schauer <f.schauer@proxmox.com>
To: pve-devel@lists.proxmox.com
Subject: [pve-devel] [PATCH qemu-server v2 7/9] refactor: move rng related code into its own module
Date: Wed, 29 Jan 2025 16:53:37 +0100 [thread overview]
Message-ID: <20250129155339.164696-8-f.schauer@proxmox.com> (raw)
In-Reply-To: <20250129155339.164696-1-f.schauer@proxmox.com>
Signed-off-by: Filip Schauer <f.schauer@proxmox.com>
---
PVE/QemuServer.pm | 83 +++---------------------
PVE/QemuServer/Makefile | 1 +
PVE/QemuServer/RNG.pm | 135 ++++++++++++++++++++++++++++++++++++++++
3 files changed, 145 insertions(+), 74 deletions(-)
create mode 100644 PVE/QemuServer/RNG.pm
diff --git a/PVE/QemuServer.pm b/PVE/QemuServer.pm
index 5cde94a1..93e65825 100644
--- a/PVE/QemuServer.pm
+++ b/PVE/QemuServer.pm
@@ -61,6 +61,7 @@ use PVE::QemuServer::Memory qw(get_current_memory);
use PVE::QemuServer::Monitor qw(mon_cmd);
use PVE::QemuServer::PCI qw(print_pci_addr print_pcie_addr print_pcie_root_port parse_hostpci);
use PVE::QemuServer::QMPHelpers qw(qemu_deviceadd qemu_devicedel qemu_objectadd qemu_objectdel);
+use PVE::QemuServer::RNG;
use PVE::QemuServer::USB;
my $have_sdn;
@@ -249,39 +250,6 @@ my $spice_enhancements_fmt = {
},
};
-my $rng_fmt = {
- source => {
- type => 'string',
- enum => ['/dev/urandom', '/dev/random', '/dev/hwrng'],
- default_key => 1,
- description => "The file on the host to gather entropy from. In most cases '/dev/urandom'"
- ." should be preferred over '/dev/random' to avoid entropy-starvation issues on the"
- ." host. Using urandom does *not* decrease security in any meaningful way, as it's"
- ." still seeded from real entropy, and the bytes provided will most likely be mixed"
- ." with real entropy on the guest as well. '/dev/hwrng' can be used to pass through"
- ." a hardware RNG from the host.",
- },
- max_bytes => {
- type => 'integer',
- description => "Maximum bytes of entropy allowed to get injected into the guest every"
- ." 'period' milliseconds. Prefer a lower value when using '/dev/random' as source. Use"
- ." `0` to disable limiting (potentially dangerous!).",
- optional => 1,
-
- # default is 1 KiB/s, provides enough entropy to the guest to avoid boot-starvation issues
- # (e.g. systemd etc...) while allowing no chance of overwhelming the host, provided we're
- # reading from /dev/urandom
- default => 1024,
- },
- period => {
- type => 'integer',
- description => "Every 'period' milliseconds the entropy-injection quota is reset, allowing"
- ." the guest to retrieve another 'max_bytes' of entropy.",
- optional => 1,
- default => 1000,
- },
-};
-
my $meta_info_fmt = {
'ctime' => {
type => 'integer',
@@ -724,7 +692,7 @@ EODESCR
},
rng0 => {
type => 'string',
- format => $rng_fmt,
+ format => $PVE::QemuServer::RNG::rng_fmt,
description => "Configure a VirtIO-based Random Number Generator.",
optional => 1,
},
@@ -2078,16 +2046,6 @@ sub parse_vga {
return $res;
}
-sub parse_rng {
- my ($value) = @_;
-
- return if !$value;
-
- my $res = eval { parse_property_string($rng_fmt, $value) };
- warn $@ if $@;
- return $res;
-}
-
sub parse_meta_info {
my ($value) = @_;
@@ -3940,20 +3898,14 @@ sub config_to_command {
}
}
- my $rng = $conf->{rng0} ? parse_rng($conf->{rng0}) : undef;
+ my $rng = $conf->{rng0} ? PVE::QemuServer::RNG::parse_rng($conf->{rng0}) : undef;
if ($rng && $version_guard->(4, 1, 2)) {
- check_rng_source($rng->{source});
-
- my $max_bytes = $rng->{max_bytes} // $rng_fmt->{max_bytes}->{default};
- my $period = $rng->{period} // $rng_fmt->{period}->{default};
- my $limiter_str = "";
- if ($max_bytes) {
- $limiter_str = ",max-bytes=$max_bytes,period=$period";
- }
-
- my $rng_addr = print_pci_addr("rng0", $bridges, $arch, $machine_type);
- push @$devices, '-object', "rng-random,filename=$rng->{source},id=rng0";
- push @$devices, '-device', "virtio-rng-pci,rng=rng0$limiter_str$rng_addr";
+ my $rng_object = PVE::QemuServer::RNG::print_rng_object('rng0', $rng);
+ my $rng_device = PVE::QemuServer::RNG::print_rng_device(
+ 'rng0', $rng, $bridges, $arch, $machine_type
+ );
+ push @$devices, '-object', $rng_object;
+ push @$devices, '-device', $rng_device;
}
my $spice_port;
@@ -4235,23 +4187,6 @@ sub config_to_command {
return wantarray ? ($cmd, $vollist, $spice_port, $pci_devices) : $cmd;
}
-sub check_rng_source {
- my ($source) = @_;
-
- # mostly relevant for /dev/hwrng, but doesn't hurt to check others too
- die "cannot create VirtIO RNG device: source file '$source' doesn't exist\n"
- if ! -e $source;
-
- my $rng_current = '/sys/devices/virtual/misc/hw_random/rng_current';
- if ($source eq '/dev/hwrng' && file_read_firstline($rng_current) eq 'none') {
- # Needs to abort, otherwise QEMU crashes on first rng access. Note that rng_current cannot
- # be changed to 'none' manually, so once the VM is past this point, it's no longer an issue.
- die "Cannot start VM with passed-through RNG device: '/dev/hwrng' exists, but"
- ." '$rng_current' is set to 'none'. Ensure that a compatible hardware-RNG is attached"
- ." to the host.\n";
- }
-}
-
sub spice_port {
my ($vmid) = @_;
diff --git a/PVE/QemuServer/Makefile b/PVE/QemuServer/Makefile
index 89d12091..72c287fc 100644
--- a/PVE/QemuServer/Makefile
+++ b/PVE/QemuServer/Makefile
@@ -1,4 +1,5 @@
SOURCES=PCI.pm \
+ RNG.pm \
USB.pm \
Memory.pm \
ImportDisk.pm \
diff --git a/PVE/QemuServer/RNG.pm b/PVE/QemuServer/RNG.pm
new file mode 100644
index 00000000..f7a62f3b
--- /dev/null
+++ b/PVE/QemuServer/RNG.pm
@@ -0,0 +1,135 @@
+package PVE::QemuServer::RNG;
+
+use strict;
+use warnings;
+
+use PVE::QemuServer::PCI qw(print_pci_addr);
+use PVE::JSONSchema;
+use PVE::Tools qw(file_read_firstline);
+use base 'Exporter';
+
+our @EXPORT_OK = qw(
+parse_rng
+check_rng_source
+print_rng_device
+print_rng_object
+);
+
+our $rng_fmt = {
+ source => {
+ type => 'string',
+ enum => ['/dev/urandom', '/dev/random', '/dev/hwrng'],
+ default_key => 1,
+ optional => 1,
+ description => "The file on the host to gather entropy from. In most cases '/dev/urandom'"
+ ." should be preferred over '/dev/random' to avoid entropy-starvation issues on the"
+ ." host. Using urandom does *not* decrease security in any meaningful way, as it's"
+ ." still seeded from real entropy, and the bytes provided will most likely be mixed"
+ ." with real entropy on the guest as well. '/dev/hwrng' can be used to pass through"
+ ." a hardware RNG from the host.",
+ },
+ max_bytes => {
+ type => 'integer',
+ description => "Maximum bytes of entropy allowed to get injected into the guest every"
+ ." 'period' milliseconds. Prefer a lower value when using '/dev/random' as source. Use"
+ ." `0` to disable limiting (potentially dangerous!).",
+ optional => 1,
+
+ # default is 1 KiB/s, provides enough entropy to the guest to avoid boot-starvation issues
+ # (e.g. systemd etc...) while allowing no chance of overwhelming the host, provided we're
+ # reading from /dev/urandom
+ default => 1024,
+ },
+ period => {
+ type => 'integer',
+ description => "Every 'period' milliseconds the entropy-injection quota is reset, allowing"
+ ." the guest to retrieve another 'max_bytes' of entropy.",
+ optional => 1,
+ default => 1000,
+ },
+};
+
+PVE::JSONSchema::register_format('pve-qm-rng', $rng_fmt);
+
+our $rngdesc = {
+ type => 'string',
+ format => $rng_fmt,
+ optional => 1,
+ description => "Configure a VirtIO-based Random Number Generator.",
+};
+PVE::JSONSchema::register_standard_option('pve-qm-rng', $rngdesc);
+
+sub parse_rng {
+ my ($value) = @_;
+
+ return if !$value;
+
+ my $res = eval { PVE::JSONSchema::parse_property_string($rng_fmt, $value) };
+ warn $@ if $@;
+
+ my $source = $res->{source};
+
+ return $res;
+}
+
+sub check_rng_source {
+ my ($source) = @_;
+
+ # mostly relevant for /dev/hwrng, but doesn't hurt to check others too
+ die "cannot create VirtIO RNG device: source file '$source' doesn't exist\n"
+ if ! -e $source;
+
+ my $rng_current = '/sys/devices/virtual/misc/hw_random/rng_current';
+ if ($source eq '/dev/hwrng' && file_read_firstline($rng_current) eq 'none') {
+ # Needs to abort, otherwise QEMU crashes on first rng access. Note that rng_current cannot
+ # be changed to 'none' manually, so once the VM is past this point, it's no longer an issue.
+ die "Cannot start VM with passed-through RNG device: '/dev/hwrng' exists, but"
+ ." '$rng_current' is set to 'none'. Ensure that a compatible hardware-RNG is attached"
+ ." to the host.\n";
+ }
+}
+
+sub get_rng_source_path {
+ my ($rng) = @_;
+
+ my $source = $rng->{source};
+
+ if (defined($source)) {
+ return $source;
+ }
+
+ return;
+}
+
+sub print_rng_device {
+ my ($id, $rng, $bridges, $arch, $machine) = @_;
+
+ return if !$rng;
+
+ my $source_path = get_rng_source_path($rng);
+ check_rng_source($source_path);
+
+ my $max_bytes = $rng->{max_bytes} // $rng_fmt->{max_bytes}->{default};
+ my $period = $rng->{period} // $rng_fmt->{period}->{default};
+ my $limiter_str = "";
+ if ($max_bytes) {
+ $limiter_str = ",max-bytes=$max_bytes,period=$period";
+ }
+
+ my $rng_addr = print_pci_addr($id, $bridges, $arch, $machine);
+
+ return "virtio-rng-pci,rng=$id$limiter_str$rng_addr";
+}
+
+sub print_rng_object {
+ my ($id, $rng) = @_;
+
+ return if !$rng;
+
+ my $source_path = get_rng_source_path($rng);
+ check_rng_source($source_path);
+
+ return "rng-random,filename=$source_path,id=$id";
+}
+
+1;
--
2.39.5
_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
next prev parent reply other threads:[~2025-01-29 15:54 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-01-29 15:53 [pve-devel] [PATCH cluster/guest-common/manager/qemu-server v2 0/9] fix #5657: allow configuring RNG device as non-root user Filip Schauer
2025-01-29 15:53 ` [pve-devel] [PATCH guest-common v2 1/9] mapping: add a hardware RNG mapping config Filip Schauer
2025-01-30 12:18 ` Fiona Ebner
2025-01-29 15:53 ` [pve-devel] [PATCH cluster v2 2/9] cfs: add 'mapping/hwrng.cfg' to observed files Filip Schauer
2025-01-29 15:53 ` [pve-devel] [PATCH manager v2 3/9] introduce hardware rng mapping api Filip Schauer
2025-01-29 15:53 ` [pve-devel] [PATCH manager v2 4/9] introduce hardware rng scanning api Filip Schauer
2025-01-29 15:53 ` [pve-devel] [PATCH manager v2 5/9] ui: add hardware RNG resource mapping Filip Schauer
2025-01-29 15:53 ` [pve-devel] [PATCH manager v2 6/9] ui: allow use of mapped hardware RNGs as entropy sources for VMs Filip Schauer
2025-01-29 15:53 ` Filip Schauer [this message]
2025-01-30 12:17 ` [pve-devel] [PATCH qemu-server v2 7/9] refactor: move rng related code into its own module Fiona Ebner
2025-01-29 15:53 ` [pve-devel] [PATCH qemu-server v2 8/9] allow non-root users to set /dev/u?random as an RNG source Filip Schauer
2025-01-30 12:18 ` Fiona Ebner
2025-01-29 15:53 ` [pve-devel] [PATCH qemu-server v2 9/9] let VirtIO RNG devices source entropy from mapped HWRNGs Filip Schauer
2025-01-30 12:17 ` [pve-devel] [PATCH cluster/guest-common/manager/qemu-server v2 0/9] fix #5657: allow configuring RNG device as non-root user Fiona Ebner
2025-02-10 15:47 ` Filip Schauer
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=20250129155339.164696-8-f.schauer@proxmox.com \
--to=f.schauer@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.