From 781d5e4163a78f0299b3efcaae3ac7aade9de76b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20Ferr=C3=A3o?= <2031761+viniciusferrao@users.noreply.github.com> Date: Fri, 31 Jul 2026 15:18:43 -0300 Subject: [PATCH] fix(dhcp): preserve Kea reservations on makedhcp -n --- perl-xCAT/xCAT/DHCP/Backend/Kea.pm | 36 ++++++++++++++++++++++++++++ xCAT-server/lib/xcat/plugins/dhcp.pm | 18 ++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/perl-xCAT/xCAT/DHCP/Backend/Kea.pm b/perl-xCAT/xCAT/DHCP/Backend/Kea.pm index 2525ae7d3..30f6a028f 100644 --- a/perl-xCAT/xCAT/DHCP/Backend/Kea.pm +++ b/perl-xCAT/xCAT/DHCP/Backend/Kea.pm @@ -630,6 +630,42 @@ sub query_reservations { return \@found; } +sub preserve_reservations { + my ( $self, $config, $intent ) = @_; + + my $target_subnets = $intent->{subnets} || []; + return $intent unless @$target_subnets; + + my $target_config = $config->{Dhcp6} + ? { Dhcp6 => { subnet6 => $target_subnets } } + : { Dhcp4 => { subnet4 => $target_subnets } }; + + foreach my $source_subnet ( _subnets_for_config($config) ) { + foreach my $reservation ( @{ $source_subnet->{reservations} || [] } ) { + my $ip = $reservation->{'ip-address'}; + $ip = $reservation->{'ip-addresses'}[0] + if !$ip && ref( $reservation->{'ip-addresses'} ) eq 'ARRAY'; + + my $target_subnet; + if ($ip) { + my $subnet_id = $self->subnet_id_for_ip( $target_config, $ip ); + $target_subnet = _find_subnet_by_id( $target_config, $subnet_id ) if defined($subnet_id); + } + if ( !$target_subnet && $source_subnet->{subnet} ) { + ($target_subnet) = grep { + ( $_->{subnet} || '' ) eq $source_subnet->{subnet} + } @$target_subnets; + } + next unless $target_subnet; + + $target_subnet->{reservations} ||= []; + push @{ $target_subnet->{reservations} }, { %$reservation }; + } + } + + return $intent; +} + sub subnet_id_for_ip { my ( $self, $config, $ip ) = @_; diff --git a/xCAT-server/lib/xcat/plugins/dhcp.pm b/xCAT-server/lib/xcat/plugins/dhcp.pm index 167b8cf20..29eee214c 100644 --- a/xCAT-server/lib/xcat/plugins/dhcp.pm +++ b/xCAT-server/lib/xcat/plugins/dhcp.pm @@ -2381,6 +2381,24 @@ sub kea_process_request } if ($opt->{n}) { + my $loaded4 = $backend->load_dhcp4_config(); + if ($loaded4->{error}) { + $callback->({ error => [ $loaded4->{error} ], errorcode => [1] }); + flock($dhcplockfd, LOCK_UN); + return; + } + $backend->preserve_reservations($loaded4, $intent4); + + if ($using_dhcp6) { + my $loaded6 = $backend->load_dhcp6_config(); + if ($loaded6->{error}) { + $callback->({ error => [ $loaded6->{error} ], errorcode => [1] }); + flock($dhcplockfd, LOCK_UN); + return; + } + $backend->preserve_reservations($loaded6, $intent6); + } + my $result = $backend->write_dhcp4_config($intent4, backup_existing => 1); if ($result->{error}) { $callback->({ error => [ $result->{error} ], errorcode => [1] });