run env: replace lsblk with hd_list but fix it up a bit

Instead of lsblk we use the original `hd_list` to be closer
to what we originally had.
However, from the PVE codebase I copied over the use of the
`E: DEVNAME` property to find the `/dev` node like (since
some weird devices can have '!' in /sys with '/' in /dev),
drop the check for `/sys/block/$d/dev`, and provide both the
`/dev` and `/sys/block` path in the output array.

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
This commit is contained in:
Wolfgang Bumiller 2023-06-20 12:01:36 +02:00 committed by Thomas Lamprecht
parent a2d3045be5
commit 4532cff472
3 changed files with 58 additions and 31 deletions

View File

@ -32,26 +32,58 @@ sub query_total_memory : prototype() {
} }
# Returns a hash. # Returns a hash.
# { # [
# name => { # [ <useless index>, "/dev/path", size_in_blocks, "model", logical_blocksize, <name as found in /sys/block> ]
# size => <bytes>, # ]
# }
# }
my sub query_blockdevs : prototype() { my sub query_blockdevs : prototype() {
my $disks = {}; my $res = [];
my $count = 0;
foreach my $bd (</sys/block/*>) {
next if $bd =~ m|^/sys/block/ram\d+$|;
next if $bd =~ m|^/sys/block/loop\d+$|;
next if $bd =~ m|^/sys/block/md\d+$|;
next if $bd =~ m|^/sys/block/dm-.*$|;
next if $bd =~ m|^/sys/block/fd\d+$|;
next if $bd =~ m|^/sys/block/sr\d+$|;
# FIXME: not the same as the battle proven way we used in the installer for years! my $info = `udevadm info --path $bd --query all`;
my $lsblk = fromjs(qx/lsblk -e 230 --bytes --json/); next if !$info;
for my $disk ($lsblk->{blockdevices}->@*) { next if $info !~ m/^E: DEVTYPE=disk$/m;
my ($name, $ro, $size, $type, $mountpoints) = $disk->@{qw(name ro size type mountpoints)}; next if $info =~ m/^E: ID_CDROM/m;
next if $info =~ m/^E: ID_FS_TYPE=iso9660/m;
next if $type ne 'disk' || $ro; my ($name) = $info =~ m/^N: (\S+)$/m;
next if grep { defined($_) } @$mountpoints; next if !$name;
$disks->{$name} = { size => $size }; my $dev_path;
if ($info =~ m/^E: DEVNAME=(\S+)$/m) {
$dev_path = $1;
} else {
$dev_path = "/dev/$name";
} }
return $disks; my $size = file_read_firstline("$bd/size");
chomp $size;
$size = undef if !($size && $size =~ m/^\d+$/);
$size = int($size);
next if !$size;
my $model = file_read_firstline("$bd/device/model") || '';
$model =~ s/^\s+//;
$model =~ s/\s+$//;
if (length ($model) > 30) {
$model = substr ($model, 0, 30);
}
my $logical_bsize = file_read_firstline("$bd/queue/logical_block_size") // '';
chomp $logical_bsize;
$logical_bsize = undef if !($logical_bsize && $logical_bsize =~ m/^\d+$/);
$logical_bsize = int($logical_bsize);
push @$res, [$count++, $dev_path, $size, $model, $logical_bsize, "/sys/block/$name"];
}
return $res;
} }
# Returns a hash. # Returns a hash.

View File

@ -223,6 +223,7 @@ pub enum AdvancedBootdiskOptions {
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq)]
pub struct Disk { pub struct Disk {
pub path: String, pub path: String,
pub model: Option<String>,
pub size: u64, pub size: u64,
} }

View File

@ -157,23 +157,17 @@ fn deserialize_disks_map<'de, D>(deserializer: D) -> Result<Vec<Disk>, D::Error>
where where
D: Deserializer<'de>, D: Deserializer<'de>,
{ {
#[derive(Deserialize)] let disks = <Vec<(usize, String, u64, String, u64, String)>>::deserialize(deserializer)?;
struct DiskDescriptor { Ok(disks
size: u64, .into_iter()
} .map(
|(_index, device, size_mb, model, logical_bsize, _syspath)| Disk {
let map: HashMap<String, DiskDescriptor> = Deserialize::deserialize(deserializer)?; size: size_mb * logical_bsize,
path: device,
let mut result = Vec::with_capacity(map.len()); model: (!model.is_empty()).then_some(model),
for (path, desc) in map.into_iter() { },
result.push(Disk { )
path: format!("/dev/{path}"), .collect())
size: desc.size,
});
}
result.sort();
Ok(result)
} }
fn deserialize_cidr_list<'de, D>(deserializer: D) -> Result<Vec<CidrAddress>, D::Error> fn deserialize_cidr_list<'de, D>(deserializer: D) -> Result<Vec<CidrAddress>, D::Error>