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.
# {
# name => {
# size => <bytes>,
# }
# }
# [
# [ <useless index>, "/dev/path", size_in_blocks, "model", logical_blocksize, <name as found in /sys/block> ]
# ]
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 $lsblk = fromjs(qx/lsblk -e 230 --bytes --json/);
for my $disk ($lsblk->{blockdevices}->@*) {
my ($name, $ro, $size, $type, $mountpoints) = $disk->@{qw(name ro size type mountpoints)};
my $info = `udevadm info --path $bd --query all`;
next if !$info;
next if $info !~ m/^E: DEVTYPE=disk$/m;
next if $info =~ m/^E: ID_CDROM/m;
next if $info =~ m/^E: ID_FS_TYPE=iso9660/m;
next if $type ne 'disk' || $ro;
next if grep { defined($_) } @$mountpoints;
my ($name) = $info =~ m/^N: (\S+)$/m;
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";
}
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 $disks;
return $res;
}
# Returns a hash.

View File

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

View File

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