Re: [PATCH ha-manager v3 35/40] implement automatic rebalancing

Daniel Kral
2026-03-31T09:42:39Z

On Tue Mar 31, 2026 at 11:07 AM CEST, Michael Köppl wrote:
> On Mon Mar 30, 2026 at 4:30 PM CEST, Daniel Kral wrote:
>> diff --git a/src/PVE/HA/Usage.pm b/src/PVE/HA/Usage.pm
>> index 43feb041..659ab30a 100644
>> --- a/src/PVE/HA/Usage.pm
>> +++ b/src/PVE/HA/Usage.pm
>> @@ -60,6 +60,40 @@ sub remove_service_usage {
>> die "implement in subclass";
>> }
>>
>> +sub calculate_node_imbalance {
>> + my ($self) = @_;
>> +
>> + die "implement in subclass";
>> +}
>> +
>> +sub score_best_balancing_migrations {
>> + my ($self, $migration_candidates, $limit) = @_;
>> +
>> + die "implement in subclass";
>> +}
>> +
>> +sub select_best_balancing_migration {
>> + my ($self, $migration_candidates) = @_;
>> +
>> + my $migrations = $self->score_best_balancing_migrations($migration_candidates, 1);
>> +
>> + return $migrations->[0];
>
> If an error occurs in the following call in
> score_best_balancing_migrations
>
> my $migrations = eval {
> $self->{scheduler}
> ->score_best_balancing_migration_candidates_topsis($migration_candidates, $limit);
> };
>
> you'd return an undefined $migrations, which would result in a
> dereference error here.
>

Hm, I can't seem to reproduce it even if I just `return undef` in
score_best_balancing_migrations{,_topsis}() and before writing this line
I tested it with:

# cat perl-array-empty.pl
#!/usr/bin/perl

use v5.36;
use Data::Dumper;

my $array1 = undef;
my $array2 = [];
my $array3 = [{}];
my $array4 = [{something => 'a'}, {else => 'b'}];

my $i = 1;
for my $var (($array1, $array2, $array3, $array4)) {
print "array$i value: " . Dumper($var);
print "array$i first: " . Dumper($var->[0]);

$i++;
}
# ./perl-array-empty.pl
array1 value: $VAR1 = undef;
array1 first: $VAR1 = undef;
array2 value: $VAR1 = [];
array2 first: $VAR1 = undef;
array3 value: $VAR1 = [
{}
];
array3 first: $VAR1 = {};
array4 value: $VAR1 = [
{
'something' => 'a'
},
{
'else' => 'b'
}
];
array4 first: $VAR1 = {
'something' => 'a'
};

Or do you have another reproducer for this?

>> +}
>> +
>> +sub score_best_balancing_migrations_topsis {
>> + my ($self, $migration_candidates, $limit) = @_;
>> +
>> + die "implement in subclass";
>> +}
>> +
>> +sub select_best_balancing_migration_topsis {
>> + my ($self, $migration_candidates) = @_;
>> +
>> + my $migrations = $self->score_best_balancing_migrations_topsis($migration_candidates, 1);
>> +
>> + return $migrations->[0];
>> +}
>> +
>> # Returns a hash with $nodename => $score pairs. A lower $score is better.
>> sub score_nodes_to_start_service {
>> my ($self, $sid) = @_;
>> diff --git a/src/PVE/HA/Usage/Dynamic.pm b/src/PVE/HA/Usage/Dynamic.pm
>> index 24c85a41..76d0feaa 100644
>> --- a/src/PVE/HA/Usage/Dynamic.pm
>> +++ b/src/PVE/HA/Usage/Dynamic.pm
>> @@ -104,6 +104,39 @@ sub remove_service_usage {
>> $self->{haenv}->log('warning', "unable to remove service '$sid' usage - $@") if $@;
>> }
>>
>
> [snip]