blob: 4b93ef7a5277a072c5c564eecef14c501d2592c1 [file] [log] [blame]
#!/usr/bin/perl
# Copyright (C) 2013 STRATO. All rights reserved.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public
# License v2 as published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public
# License along with this program; if not, write to the
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 021110-1307, USA.
# WARNING: if you create large tests, inode assumptions by refgen.pl will break
# on btrfs and on zfs.
use strict;
use warnings;
sub get_next_offset {
my ($old, $increment, $numbers) = @_;
my $new = $old;
while ($numbers =~ /(\d+)/g) {
$new = $1 + $increment if ($new < $1 + $increment);
}
return $new;
}
sub line_split {
my $line = shift;
if ($line =~ s/^(mk\S+) (\S+ \S+)//) {
# mk* commands have <ino> <name> as first 2 args
} elsif ($line =~ s/^(link|rename) (\S+ \S+)//) {
# link|rename commands have <name> <name> as first 2 args
} elsif ($line =~ s/^(\S+) (\S+)//) {
# other commands only have <name> as first arg
} elsif ($line =~ s/^(\S+)$//) {
# snapshot|remount commands have no args at all
} else {
die "line format not recognized in line $.\n";
}
return ($1, $2, $line);
}
my $next_offset = 0;
my %offset = ();
my $remount = 0;
my $snap = 0;
while (1) {
my $generated = 0;
my $cmd = "";
foreach my $file (@ARGV) {
if (!open(F, "<", $file)) {
warn "skip! cannot open $file: $!\n";
next;
}
my $header = 0;
my $skip_snap = 0;
my $skip_remount = 0;
$offset{$file} = $next_offset if (!exists $offset{$file});
while (my $line = <F>) {
# skip everything up to the current snapshot
if ($skip_snap < $snap) {
++$skip_snap if ($line =~ m/^snapshot$/);
next;
}
if ($skip_remount < $remount) {
++$skip_remount if ($line =~ m/^remount$/);
next;
}
next if ($line =~ /^\s*#/ or $line =~ /^\s*$/);
if ($line =~ /^(snapshot|remount)$/) {
$cmd = $1;
last;
}
my ($cmd, $inodes, $args) = line_split($line);
if (!$header) {
print "# start snap $snap remount $remount " .
"file $file inode offset $offset{$file}" .
"\n";
$header = 1;
}
if ($snap == 0 && $remount == 0) {
$next_offset = get_next_offset($next_offset,
$offset{$file},
$inodes);
}
$inodes =~ s/(\d+)/$1 + $offset{$file}/ge;
print $cmd, " ", $inodes, $args;
$generated++;
}
while ($snap == 0 && $remount == 0 && (my $line = <F>)) {
next if ($line =~ /^\s*#/ or $line =~ /^\s*$/);
my ($cmd, $inodes, $args) = line_split($line);
next if !defined $inodes;
$next_offset = get_next_offset($next_offset,
$offset{$file}, $inodes);
}
close(F);
}
last if (!$generated);
if ($cmd eq "snapshot") {
++$snap;
$remount = 0;
} elsif ($cmd eq "remount") {
++$remount;
} else {
die "command $cmd";
}
print $cmd, "\n";
}