Speed up deletion and creation of a large number of records https://github.com/webmin/webmin/issues/1434

This commit is contained in:
Jamie Cameron
2021-01-16 12:15:46 -08:00
parent 7f3fd2a7fe
commit ec0755d6db
2 changed files with 49 additions and 14 deletions

View File

@@ -3491,25 +3491,27 @@ return $out if ($tries >= 10);
# Merge records back into original file, by deleting all NSEC and RRSIG records
# and then copying over
for(my $i=$#recs; $i>=0; $i--) {
if ($recs[$i]->{'type'} eq 'NSEC' ||
$recs[$i]->{'type'} eq 'NSEC3' ||
$recs[$i]->{'type'} eq 'RRSIG' ||
$recs[$i]->{'type'} eq 'NSEC3PARAM') {
&delete_record($fn, $recs[$i]);
my @delrecs;
foreach my $r (@recs) {
if ($r->{'type'} eq 'NSEC' ||
$r->{'type'} eq 'NSEC3' ||
$r->{'type'} eq 'RRSIG' ||
$r->{'type'} eq 'NSEC3PARAM') {
push(@delrecs, $r);
}
}
&delete_multiple_records($fn, \@delrecs);
my @signedrecs = &read_zone_file($fn.".webmin-signed", $dom);
my @addrecs;
foreach my $r (@signedrecs) {
if ($r->{'type'} eq 'NSEC' ||
$r->{'type'} eq 'NSEC3' ||
$r->{'type'} eq 'RRSIG' ||
$r->{'type'} eq 'NSEC3PARAM') {
&create_record($fn, $r->{'name'}, $r->{'ttl'}, $r->{'class'},
$r->{'type'}, join(" ", @{$r->{'values'}}),
$r->{'comment'});
push(@addrecs, $r);
}
}
&create_multiple_records($fn, \@addrecs);
&unlink_file($signed);
return undef;
}

View File

@@ -327,10 +327,27 @@ return @rv;
# Add a new record of some type to some zone file
sub create_record
{
my $fn = &make_chroot(&absolute_path($_[0]));
my ($file, @rec) = @_;
my $fn = &make_chroot(&absolute_path($file));
&is_raw_format_records($fn) && &error("Raw format zone files cannot be edited");
my $lref = &read_file_lines($fn);
push(@$lref, &make_record(@_[1..$#_]));
push(@$lref, &make_record(@rec));
&flush_file_lines($fn);
}
# create_multiple_records(file, &records)
# Create records from structures
sub create_multiple_records
{
my ($file, $recs) = @_;
my $fn = &make_chroot(&absolute_path($file));
&is_raw_format_records($fn) && &error("Raw format zone files cannot be edited");
my $lref = &read_file_lines($fn);
foreach my $r (@$recs) {
push(@$lref, &make_record($r->{'name'}, $r->{'ttl'}, $r->{'class'},
$r->{'type'}, join(" ", @{$r->{'values'}}),
$r->{'comment'}));
}
&flush_file_lines($fn);
}
@@ -350,11 +367,27 @@ splice(@$lref, $_[1]->{'line'}, $lines, &make_record(@_[2..$#_]));
# Deletes a record in some zone file
sub delete_record
{
my $fn = &make_chroot(&absolute_path($_[0]));
my ($file, $r) = @_;
my $fn = &make_chroot(&absolute_path($file));
&is_raw_format_records($fn) && &error("Raw format zone files cannot be edited");
my $lref = &read_file_lines($fn);
my $lines = $_[1]->{'eline'} - $_[1]->{'line'} + 1;
splice(@$lref, $_[1]->{'line'}, $lines);
my $lines = $r->{'eline'} - $r->{'line'} + 1;
splice(@$lref, $r->{'line'}, $lines);
&flush_file_lines($fn);
}
# delete_multiple_records(file, &records)
# Delete many records from the same file at once
sub delete_multiple_records
{
my ($file, $recs) = @_;
my $fn = &make_chroot(&absolute_path($file));
&is_raw_format_records($fn) && &error("Raw format zone files cannot be edited");
my $lref = &read_file_lines($fn);
foreach my $r (sort { $b->{'line'} <=> $a->{'line'} } @$recs) {
my $lines = $r->{'eline'} - $r->{'line'} + 1;
splice(@$lref, $r->{'line'}, $lines);
}
&flush_file_lines($fn);
}