mirror of
https://github.com/linux-apfs/apfstests.git
synced 2026-05-01 15:01:44 -07:00
cmd/xfs/tools/README.auto-qa 1.1 Renamed to cmd/xfstests/tools/README.auto-qa
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
Quick guide to auto-qa dxm 04/10/2000
|
||||
______________________ ______________
|
||||
|
||||
|
||||
- pick/create a user to run auto-qa and check they
|
||||
can use ptools to check out of the tree
|
||||
- add your host to cmd/xfs/stress/common.config
|
||||
- add your host to cmd/xfs/tools/auto-qa
|
||||
check both these files in
|
||||
- make a directory "$HOME/qa"
|
||||
- make a workarea "$HOME/qa/linux-xfs" for linux-xfs
|
||||
(easiest to copy one from elsewhere)
|
||||
- cd $HOME/qa ; ln -s linux-xfs/cmd/xfs/tools/auto-qa .
|
||||
(auto-qa must be a link into it's own source tree
|
||||
so it can update itself)
|
||||
- copy an appropriate .config file to
|
||||
$HOME/qa/$HOSTNAME-2.4.0-xfs-qa.config
|
||||
- You'll need a hacked version of 'su' in $HOME/qa that
|
||||
lets your user su to root/root without a password
|
||||
(if you want to run from cron, it mustn't require
|
||||
/dev/tty). Warning - this is a massive security
|
||||
hole.
|
||||
- chown root.root $HOME/qa/su
|
||||
- chmod 6755 $HOME/qa/su
|
||||
- add the soon to be kernel to /etc/lilo.conf
|
||||
|
||||
image=/boot/vmlinuz-2.4.0-xfs-qa
|
||||
label=linux-xfs-qa
|
||||
append = "console=ttyS0,38400n8"
|
||||
|
||||
- $HOME/qa/auto-qa init
|
||||
|
||||
At this point, the script should update the workarea, clean it,
|
||||
rebuild it, install it and reboot.
|
||||
|
||||
Then run
|
||||
|
||||
- $HOME/qa/auto-qa restarted
|
||||
|
||||
And the tests should happen... and all pass, of course.
|
||||
|
||||
To get it going automagically:
|
||||
|
||||
- add some lines to the appropriate user's crontab:
|
||||
|
||||
0 4 * * * $HOME/qa/auto-qa cron-init
|
||||
30 4 * * * $HOME/qa/auto-qa cron-restarted
|
||||
|
||||
Notes:
|
||||
- if MODULAR=1 in auto-qa XFS and pagebuf are expected to
|
||||
be modules. if MODULAR=0 they should be built into
|
||||
the kernel
|
||||
- the test device is cleaned at the start of the QA run
|
||||
(to stop nightly QA being stuffed up if someone
|
||||
leaves the device inconsistant etc)
|
||||
- I'm using a hacked su because PCP sudo won't set the
|
||||
gid properly, and normal linux su won't run
|
||||
without a tty even if PAM is pissed-off.
|
||||
- The QA is restarted after reboot by a second cron entry
|
||||
to avoid the test being able to get itself into
|
||||
some stupid loop and so that it's always started
|
||||
by the appropriate user. You might have to make
|
||||
the second cron run later if your build takes ages.
|
||||
- Point the email addresses somewhere appropriate
|
||||
- When run in "cron-init" or "init" states, the script
|
||||
will p_tupdate itself and restart. If you start
|
||||
with an empty source tree, you'll need to check
|
||||
out the cmd/xfs/tools/auto-qa script before it'll
|
||||
work (duh).
|
||||
|
||||
good luck.
|
||||
Executable
+537
File diff suppressed because it is too large
Load Diff
Executable
+211
@@ -0,0 +1,211 @@
|
||||
#!/usr/bin/perl -w
|
||||
|
||||
#
|
||||
# Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it
|
||||
# under the terms of version 2 of the GNU General Public License as
|
||||
# published by the Free Software Foundation.
|
||||
#
|
||||
# This program is distributed in the hope that it would be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
#
|
||||
# Further, this software is distributed without any warranty that it is
|
||||
# free of the rightful claim of any third person regarding infringement
|
||||
# or the like. Any license provided herein, whether implied or
|
||||
# otherwise, applies only to this software file. Patent licenses, if
|
||||
# any, provided herein do not apply to combinations of this program with
|
||||
# other software, or any other product whatsoever.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write the Free Software Foundation, Inc., 59
|
||||
# Temple Place - Suite 330, Boston MA 02111-1307, USA.
|
||||
#
|
||||
# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
|
||||
# Mountain View, CA 94043, or:
|
||||
#
|
||||
# http://www.sgi.com
|
||||
#
|
||||
# For further information regarding this notice, see:
|
||||
#
|
||||
# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
|
||||
#
|
||||
|
||||
#
|
||||
# use db to try to traverse the entire filesystem starting at the root
|
||||
#
|
||||
# dxm 5/10/00
|
||||
|
||||
my $device;
|
||||
my $rootino;
|
||||
my $agcount;
|
||||
my $versionnum;
|
||||
my $dir_version;
|
||||
my @dir_inodes;
|
||||
my @bmap_blocks;
|
||||
my @block_inodes;
|
||||
my $mode;
|
||||
|
||||
sub db($)
|
||||
{
|
||||
my ($args)=@_;
|
||||
my ($ret);
|
||||
|
||||
$ret=`xfs_db -r $args $device 2> /dev/null`;
|
||||
die "ERROR executing xfs_db -r $args $device" if ($?);
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
sub fmt($)
|
||||
{
|
||||
my ($text)=@_;
|
||||
my $c=0;
|
||||
print " ";
|
||||
foreach (split("\n",$text)) {
|
||||
s/^core\.//;
|
||||
|
||||
if ($c+length($_) >= 70) {
|
||||
$c=0;
|
||||
print ",\n ";
|
||||
}
|
||||
if ($c) {
|
||||
print ", ";
|
||||
$c+=2;
|
||||
}
|
||||
print "$_";
|
||||
$c+=length($_)+2;
|
||||
}
|
||||
print "\n";
|
||||
}
|
||||
|
||||
sub inode($)
|
||||
{
|
||||
my ($num)=@_;
|
||||
my ($t);
|
||||
|
||||
@dir_inodes=();
|
||||
|
||||
$t=db("-c \"inode $num\" -c \"print\"");
|
||||
print " *** Inode $num\n";
|
||||
fmt($t);
|
||||
|
||||
($mode)= $t=~ /^core.mode = (\d+)$/m;
|
||||
|
||||
if ($t=~ /a\.bmx/m) {
|
||||
bmap("inode $num","attr");
|
||||
foreach (@bmap_blocks) {
|
||||
attr_block($_);
|
||||
}
|
||||
}
|
||||
if (eval "$mode & 040000") {
|
||||
if ( $t=~ /sfdir/m) {
|
||||
while ($t=~ /inumber(?:\.i[48])? = (\d+)$/mg) {
|
||||
push(@dir_inodes,$1);
|
||||
}
|
||||
}
|
||||
if ( $t=~ /u\.bmx/m) {
|
||||
bmap("inode $num","dir");
|
||||
foreach (@bmap_blocks) {
|
||||
dir_block($_);
|
||||
push(@dir_inodes,@block_inodes);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
bmap("inode $num","file") if ( $t=~ /u\.bmx/m);
|
||||
}
|
||||
}
|
||||
|
||||
sub bmap($$)
|
||||
{
|
||||
my ($cmd,$type)=@_;
|
||||
my ($t);
|
||||
|
||||
@bmap_blocks=();
|
||||
|
||||
$flag=($type eq "attr")?"-a":"";
|
||||
|
||||
$t=db("-c \"$cmd\" -c \"bmap $flag\"");
|
||||
print " *** bmap $type $cmd\n";
|
||||
fmt($t);
|
||||
|
||||
if ($type eq "dir" || $type eq "attr") {
|
||||
while ($t=~ /startblock (\d+) \(.+\) count (\d+)/mg) {
|
||||
for ($b=$1;$b<$1+$2;$b++) {
|
||||
push(@bmap_blocks,$b);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub dir_block($)
|
||||
{
|
||||
my ($num)=@_;
|
||||
my ($t);
|
||||
|
||||
@block_inodes=();
|
||||
|
||||
$type=($dir_version==2)?"dir2":"dir";
|
||||
|
||||
$t=db("-c \"fsblock $num\" -c \"type $type\" -c \"print\"");
|
||||
print " *** $type block $num\n";
|
||||
# need to drop . and ..
|
||||
($self)= $t=~ /\[(\d+)\].name = \"\.\"/m;
|
||||
($parent)= $t=~ /\[(\d+)\].name = \"\.\.\"/m;
|
||||
fmt($t);
|
||||
|
||||
|
||||
while ($t=~ /\[(\d+)\].inumber = (\d+)/mg) {
|
||||
next if (defined $self && $1 == $self);
|
||||
next if (defined $parent && $1 == $parent);
|
||||
push(@block_inodes, $2);
|
||||
}
|
||||
}
|
||||
|
||||
sub attr_block($)
|
||||
{
|
||||
my ($num)=@_;
|
||||
my ($t);
|
||||
|
||||
$t=db("-c \"fsblock $num\" -c \"type attr\" -c \"print\"");
|
||||
print " *** attr block $num\n";
|
||||
|
||||
fmt($t);
|
||||
}
|
||||
|
||||
sub sb($)
|
||||
{
|
||||
my ($num)=@_;
|
||||
my ($t);
|
||||
|
||||
$t=db("-c \"sb $num\" -c \"print\"");
|
||||
print " *** SB $num\n";
|
||||
fmt($t);
|
||||
|
||||
($rootino)= $t=~ /^rootino = (\d+)$/m;
|
||||
($agcount)= $t=~ /^agcount = (\d+)$/m;
|
||||
($versionnum)= $t=~ /^versionnum = (0x[\da-f]+)$/m;
|
||||
$dir_version = (eval "$versionnum & 0x2000")?2:1;
|
||||
}
|
||||
|
||||
die "Usage: $0 <XFS device>\n" unless (@ARGV == 1);
|
||||
|
||||
$device=shift @ARGV;
|
||||
die "can't read $device\n" unless (-r $device);
|
||||
die "$device is not a block device\n" unless (-b _);
|
||||
|
||||
chomp($HOST = `hostname -s`);
|
||||
|
||||
print "*** db-walk host $HOST device $device\n";
|
||||
|
||||
sb(0);
|
||||
for ($ag=1;$ag<$agcount;$ag++) {
|
||||
sb($ag);
|
||||
}
|
||||
|
||||
@inodes=($rootino);
|
||||
while ($_ = shift @inodes) {
|
||||
inode($_);
|
||||
push(@inodes,@dir_inodes);
|
||||
}
|
||||
Executable
+117
@@ -0,0 +1,117 @@
|
||||
#!/usr/bin/perl -w
|
||||
|
||||
#
|
||||
# Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it
|
||||
# under the terms of version 2 of the GNU General Public License as
|
||||
# published by the Free Software Foundation.
|
||||
#
|
||||
# This program is distributed in the hope that it would be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
#
|
||||
# Further, this software is distributed without any warranty that it is
|
||||
# free of the rightful claim of any third person regarding infringement
|
||||
# or the like. Any license provided herein, whether implied or
|
||||
# otherwise, applies only to this software file. Patent licenses, if
|
||||
# any, provided herein do not apply to combinations of this program with
|
||||
# other software, or any other product whatsoever.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write the Free Software Foundation, Inc., 59
|
||||
# Temple Place - Suite 330, Boston MA 02111-1307, USA.
|
||||
#
|
||||
# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
|
||||
# Mountain View, CA 94043, or:
|
||||
#
|
||||
# http://www.sgi.com
|
||||
#
|
||||
# For further information regarding this notice, see:
|
||||
#
|
||||
# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
|
||||
#
|
||||
|
||||
#
|
||||
# traverse the entire filesystem dumping info.
|
||||
#
|
||||
# dxm 5/10/00
|
||||
use MD5;
|
||||
use Getopt::Std;
|
||||
|
||||
my %opt;
|
||||
|
||||
sub scan($)
|
||||
{
|
||||
my ($file)=@_;
|
||||
my ($md5)=new MD5;
|
||||
my (@stat);
|
||||
|
||||
unless (@stat=lstat("$file")) {
|
||||
printf("%-" . ($opt{v}?65:32) . "s $file\n", "!!! could not lstat");
|
||||
return;
|
||||
}
|
||||
|
||||
$stat[0]=$stat[8]=""; # wipe the device and access time
|
||||
$md5->reset;
|
||||
$md5->add(join(" ",@stat));
|
||||
|
||||
print join(" ",@stat), "\n";
|
||||
|
||||
if ($opt{v}) {
|
||||
print $md5->hexdigest . " ";
|
||||
$md5->reset;
|
||||
}
|
||||
|
||||
if (-l "$file") {
|
||||
if (!defined($link = readlink $file)) {
|
||||
printf("%-32s $file\n", "!!! could not readlink");
|
||||
return;
|
||||
}
|
||||
$md5->add($link);
|
||||
} elsif (-f "$file") {
|
||||
if (!open(FILE, "$file")) {
|
||||
printf("%-32s $file\n", "!!! could not read");
|
||||
return;
|
||||
}
|
||||
$md5->addfile(FILE);
|
||||
close (FILE);
|
||||
}
|
||||
print $md5->hexdigest . " $file\n";
|
||||
}
|
||||
|
||||
getopts('vs', \%opt);
|
||||
|
||||
die "Usage: $0 <dir>\n" unless (@ARGV == 1);
|
||||
|
||||
$dir=shift @ARGV;
|
||||
die "can't read $dir\n" unless (-r $dir);
|
||||
die "$dir is not a directory\n" unless (-d _);
|
||||
|
||||
chomp($HOST = `hostname -s`);
|
||||
|
||||
print "*** fs-walk host $HOST dir $dir\n";
|
||||
|
||||
@todo=$dir;
|
||||
while ($dir = shift @todo) {
|
||||
scan($dir);
|
||||
unless (opendir(DIR,$dir)) {
|
||||
printf("%-" . ($opt{v}?65:32) . "s $dir\n", "!!! could not opendir");
|
||||
next;
|
||||
}
|
||||
unless (@all=readdir(DIR)) {
|
||||
printf("%-" . ($opt{v}?65:32) . "s $dir\n", "!!! could not readdir");
|
||||
next;
|
||||
}
|
||||
closedir(DIR);
|
||||
@dirs=grep(-d "$dir/$_" && !-l "$dir/$_", @all);
|
||||
foreach (@all) {
|
||||
next if /^\.\.?$/;
|
||||
scan("$dir/$_");
|
||||
}
|
||||
|
||||
foreach (grep(!/^\.\.?$/, @dirs)) {
|
||||
push (@todo,"$dir/$_");
|
||||
}
|
||||
}
|
||||
|
||||
Executable
+99
@@ -0,0 +1,99 @@
|
||||
#!/usr/sbin/perl
|
||||
|
||||
sub setup()
|
||||
{
|
||||
$PATH="$PATH:/usr/local/bin/ptools:/sbin:/usr/sbin";
|
||||
$DISPLAY="clouds:0";
|
||||
|
||||
if ("$HOST" eq "bruce") {
|
||||
$TOOLS="/home/dxm/isms/slinx-xfs/cmd/xfs/tools";
|
||||
$SCRATCH_DEV="/dev/sdf1";
|
||||
$SCRATCH_MNT="/mnt/xfs3";
|
||||
$MKFS="/sbin/mkfs -t xfs -f";
|
||||
$SUDO="/home/dxm/su -c";
|
||||
$MOUNT="/bin/mount -t xfs";
|
||||
$UMOUNT="/bin/umount";
|
||||
$MKFS_EXTRA="-f";
|
||||
} elsif ("$HOST" eq "whack") {
|
||||
$TOOLS="/hosts/snort/build1/people/dxm/isms/slinx-xfs/cmd/xfs/tools";
|
||||
$SCRATCH_DEV="/dev/dsk/20000080e5114459/lun2s0/c2p1";
|
||||
$SCRATCH_MNT="/lun2";
|
||||
$MKFS="/sbin/mkfs";
|
||||
$SUDO="su root -c";
|
||||
$MOUNT="/sbin/mount -t xfs";
|
||||
$UMOUNT="/sbin/umount";
|
||||
$MKFS_EXTRA="";
|
||||
} else {
|
||||
die "unconfigured host \"$HOST\"\n"
|
||||
}
|
||||
}
|
||||
|
||||
sub run_no_check(@)
|
||||
{
|
||||
system(@_);
|
||||
}
|
||||
|
||||
sub run(@)
|
||||
{
|
||||
system(@_) == 0
|
||||
|| die "ERROR \"" . join(" ",@_) . "\" returned error\n";
|
||||
}
|
||||
|
||||
sub run_expect_fail(@)
|
||||
{
|
||||
system(@_) == 0
|
||||
&& die "ERROR \"" . join(" ",@_) . "\" returned non-error\n";
|
||||
}
|
||||
|
||||
sub umount_no_check()
|
||||
{
|
||||
run_no_check("umount $SCRATCH_DEV");
|
||||
}
|
||||
|
||||
sub umount()
|
||||
{
|
||||
run("umount $SCRATCH_DEV");
|
||||
}
|
||||
|
||||
sub mount($)
|
||||
{
|
||||
my ($ops)=@_;
|
||||
run("mount -t xfs $ops $SCRATCH_DEV $SCRATCH_MNT");
|
||||
}
|
||||
|
||||
chomp($HOST=`hostname -s`);
|
||||
|
||||
die "usage: $ARGV0 <operation> [parameters]\n" unless (scalar(@ARGV));
|
||||
print "*** $HOST: Interop started\n";
|
||||
print " *** ", join(" ", @ARGV), "\n";
|
||||
|
||||
setup();
|
||||
|
||||
$op=shift(@ARGV);
|
||||
|
||||
umount_no_check();
|
||||
|
||||
if ($op eq "init") {
|
||||
|
||||
run("mkfs -t xfs $MKFS_EXTRA $SCRATCH_DEV");
|
||||
|
||||
} elsif ($op eq "test") {
|
||||
|
||||
run("xfs_repair -n $SCRATCH_DEV");
|
||||
|
||||
} elsif ($op eq "easy") {
|
||||
|
||||
mount("");
|
||||
system("mount");
|
||||
mkdir("$SCRATCH_MNT/fish",0777);
|
||||
|
||||
} elsif ($op eq "check") {
|
||||
|
||||
mount("-o ro");
|
||||
system("cd $SCRATCH_MNT ; $TOOLS/fs-walk .");
|
||||
|
||||
} else {
|
||||
die "unknown operation \"$op\"\n";
|
||||
}
|
||||
|
||||
umount_no_check();
|
||||
Executable
+267
@@ -0,0 +1,267 @@
|
||||
#!/usr/bin/perl -w
|
||||
use strict;
|
||||
#
|
||||
# srcdiff is used to compare current user level code with the current
|
||||
# kernel code and advise of any differences between files which are
|
||||
# sharing some or all of their content.
|
||||
#
|
||||
# There are two classes of sharing which we will check - header files
|
||||
# in the include directory, which must be exactly the same (use diff)
|
||||
# and source files which contain routines which must be exactly the
|
||||
# same (but the userland file is always a subset of the kernel file,
|
||||
# and hence a more flexible mechanism to "diff" is required).
|
||||
#
|
||||
# NB: to cross check that srcdiff is finding all the functions in the
|
||||
# user source file, providing you have "mkproto" installed, you
|
||||
# can "cd cmd/xfs/libxfs" and cut&paste this into a bourne shell:
|
||||
# $ for file in xfs_*.c; do
|
||||
# > mkproto -nps < $file | perl -ne '
|
||||
# > END { print " $count\t- " }
|
||||
# > s/^.* (xfs\w+|\*xfs\w+|xlog\w+|\*xlog\w+) \(.*/\1/ && { $count++ }'
|
||||
# > echo $file
|
||||
# > done
|
||||
# (compare this to "srcdiff | fgrep Total:") ... repeat for logprint.
|
||||
#
|
||||
|
||||
die "WORKAREA not set" unless defined $ENV{'WORKAREA'};
|
||||
chdir $ENV{'WORKAREA'};
|
||||
my $xdiff = $ENV{'XDIFF'};
|
||||
my $quiet=0;
|
||||
my $usage=0;
|
||||
|
||||
foreach (@ARGV) {
|
||||
if (/^-q$/) {
|
||||
$quiet++;
|
||||
} else {
|
||||
print STDERR "Illegal option $_\n";
|
||||
$usage++;
|
||||
}
|
||||
}
|
||||
|
||||
if ($usage) {
|
||||
print STDERR "Usage: $0 [-q]\n";
|
||||
exit 1;
|
||||
}
|
||||
|
||||
my @difflist = qw(
|
||||
xfs_ag.h xfs_alloc.h xfs_alloc_btree.h xfs_arch.h
|
||||
xfs_attr_leaf.h xfs_attr_sf.h xfs_bit.h xfs_bmap.h
|
||||
xfs_bmap_btree.h xfs_btree.h xfs_buf_item.h
|
||||
xfs_da_btree.h xfs_dfrag.h xfs_dinode.h xfs_dir.h
|
||||
xfs_dir2.h xfs_dir2_block.h xfs_dir2_data.h
|
||||
xfs_dir2_leaf.h xfs_dir2_node.h xfs_dir2_sf.h
|
||||
xfs_dir_leaf.h xfs_dir_sf.h xfs_dqblk.h xfs_dquot_item.h
|
||||
xfs_extfree_item.h xfs_ialloc.h xfs_imap.h
|
||||
xfs_ialloc_btree.h xfs_inode.h xfs_inode_item.h
|
||||
xfs_inum.h xfs_log.h xfs_log_priv.h xfs_log_recover.h
|
||||
xfs_mount.h xfs_quota.h xfs_rtalloc.h
|
||||
xfs_sb.h xfs_trans.h xfs_trans_space.h xfs_types.h
|
||||
);
|
||||
|
||||
sub straightdiff {
|
||||
my ( $file, $prefix1, $prefix2 ) = @_;
|
||||
|
||||
`diff $prefix1/$file $prefix2/$file >/dev/null 2>&1`;
|
||||
if (!$quiet) {
|
||||
print sprintf("\t%-35s ... ", $file);
|
||||
if ($? != 0) { print "FAILED\n"; }
|
||||
else { print "ok\n"; }
|
||||
} elsif ($? != 0) {
|
||||
printf("\t%-35s ... ", $file);
|
||||
print "FAILED\n";
|
||||
}
|
||||
}
|
||||
|
||||
print "\n=== Checking headers ===\n";
|
||||
foreach (@difflist) {
|
||||
straightdiff $_, 'cmd/xfs/include', 'linux/fs/xfs';
|
||||
}
|
||||
straightdiff 'xfs_cred.h', 'cmd/xfs/include', 'linux/fs/xfs/linux';
|
||||
straightdiff 'xfs_fs.h', 'cmd/xfs/include', 'linux/include/linux';
|
||||
straightdiff 'attributes.h', 'cmd/xfs/include', 'linux/include/linux';
|
||||
straightdiff 'acl.h', 'cmd/xfs/include', 'linux/fs/xfs/pseudo-inc/sys';
|
||||
straightdiff 'arch.h', 'cmd/xfs/include', 'linux/fs/xfs/support';
|
||||
straightdiff 'xqm.h', 'cmd/xfs/include', 'linux/include/linux';
|
||||
|
||||
#
|
||||
# setstate
|
||||
# Implements a tri-state FSA, see comments for state transitions
|
||||
# (knows about the way the XFS kernel code is written, & makes
|
||||
# some assumptions so as to not need to parse generic C code).
|
||||
# Accepts one line at a time from a source file, picking out the
|
||||
# function bodies so they can be subsequently compared.
|
||||
#
|
||||
|
||||
my $line; # line number in current source file
|
||||
my $state; # current FSA state
|
||||
my $funcbody; # current function body (contents)
|
||||
|
||||
sub setstate {
|
||||
my ( $newline ) = @_;
|
||||
$line++;
|
||||
|
||||
# - state 0:
|
||||
# if line looks like start of a function, transition to 1
|
||||
# & squirrel line away as line 1 of current function
|
||||
if ($state == 0) {
|
||||
if ($newline =~ m/^[xfs|xlog]/) {
|
||||
$state = 1;
|
||||
$funcbody = $newline;
|
||||
}
|
||||
}
|
||||
|
||||
# - state 1:
|
||||
# if line looks like start of a function, stay here
|
||||
# & squirrel line away as line 1 of current function
|
||||
# otherwise if line isn't start of function body,
|
||||
# squirrel line away as next line of current function
|
||||
# (args/..., but not sure this is a real function yet)
|
||||
# otherwise (start of function)
|
||||
# squirrel line away as next line of current function
|
||||
# transition to state 2
|
||||
elsif ($state == 1) {
|
||||
if ($newline =~ m/^[xfs|xlog]/) {
|
||||
$funcbody = $newline;
|
||||
}
|
||||
elsif ($newline =~ m/^\{/) {
|
||||
$state = 2;
|
||||
$funcbody .= $newline;
|
||||
}
|
||||
}
|
||||
|
||||
# - state 2:
|
||||
# if line looks like end of function body,
|
||||
# squirrel line away as last line of current function
|
||||
# tell someone we have a complete function ready
|
||||
# transition to state 0
|
||||
# otherwise
|
||||
# squirrel line away as next line of current function
|
||||
elsif ($state == 2) {
|
||||
$funcbody .= $newline;
|
||||
if ($newline =~ m/^\}/) {
|
||||
$state = 0;
|
||||
return $funcbody;
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
die "unknown state transition";
|
||||
}
|
||||
return undef; # i.e. not at end of a function
|
||||
}
|
||||
|
||||
sub listfuncs {
|
||||
my ( $file ) = @_;
|
||||
my @funcs;
|
||||
|
||||
$funcbody = '';
|
||||
$state = $line = 0;
|
||||
|
||||
open(USER, "$file") || die "cannot open $file";
|
||||
while (<USER>) {
|
||||
my $func = setstate($_);
|
||||
push @funcs, $func if (defined($func)); # store function away
|
||||
}
|
||||
close USER;
|
||||
return @funcs;
|
||||
}
|
||||
|
||||
sub hashfuncs {
|
||||
my ( $file ) = @_;
|
||||
my %funcs;
|
||||
|
||||
$funcbody = '';
|
||||
$state = $line = 0;
|
||||
|
||||
open(KERN, "$file") || die "cannot open $file";
|
||||
while (<KERN>) {
|
||||
my $func = setstate($_);
|
||||
if (defined($func)) {
|
||||
$func =~ m/^([xfs|xlog]\w+)\s*\(/;
|
||||
next unless defined($1);
|
||||
my $name = $1;
|
||||
if (defined($func)) {
|
||||
$funcs{$name} = $func; # store function away
|
||||
}
|
||||
}
|
||||
}
|
||||
close KERN;
|
||||
return %funcs;
|
||||
}
|
||||
|
||||
sub diffme {
|
||||
my ( $sa, $sb ) = @_;
|
||||
|
||||
return unless defined($xdiff);
|
||||
|
||||
open(FILEA, "> /tmp/diff.user.$$") || die "cannot write to /tmp/diff.user.$$";
|
||||
open(FILEB, "> /tmp/diff.kern.$$") || die "cannot write to /tmp/diff.kern.$$";
|
||||
print FILEA $sa;
|
||||
print FILEB $sb;
|
||||
close FILEA;
|
||||
close FILEB;
|
||||
`$xdiff /tmp/diff.user.$$ /tmp/diff.kern.$$`;
|
||||
unlink ("/tmp/diff.user.$$","/tmp/diff.kern.$$");
|
||||
}
|
||||
|
||||
sub functiondiff {
|
||||
my ( $file, $prefix1, $prefix2 ) = @_;
|
||||
my $plural = '';
|
||||
my $count = 0;
|
||||
my $name;
|
||||
my $found = 0;
|
||||
|
||||
print "\n=== Checking $file routines ===\n" unless ($quiet);
|
||||
|
||||
# iterate over user funcs, match up to kernel funcs
|
||||
#
|
||||
my @user = listfuncs "$prefix1/$file";
|
||||
my %kern = hashfuncs "$prefix2/$file";
|
||||
|
||||
foreach my $userfunc (@user) {
|
||||
|
||||
$userfunc =~ m/^([xfs|xlog]\w+)\s*\(/;
|
||||
next unless (defined($1));
|
||||
$name = $1;
|
||||
$count++;
|
||||
|
||||
if (exists($kern{$name})) {
|
||||
if ($userfunc ne $kern{$name}) {
|
||||
print "\n=== $file routines ===\n"
|
||||
if (!$found++ && $quiet);
|
||||
|
||||
printf("\t%-35s ... ", $name);
|
||||
print "FAILED\n";
|
||||
diffme $userfunc, $kern{$name};
|
||||
}
|
||||
elsif (!$quiet) {
|
||||
printf("\t%-35s ... ", $name);
|
||||
print "ok\n";
|
||||
}
|
||||
}
|
||||
else {
|
||||
print "Cannot find kernel function $userfunc";
|
||||
print " in file $prefix2/$file\n";
|
||||
}
|
||||
}
|
||||
($count != 1) && ( $plural = 's' );
|
||||
print "( Total: $count routine$plural checked in $file )\n" unless ($quiet);
|
||||
}
|
||||
|
||||
# cmd/xfs/{libxfs,logprint}/* fs/xfs/*
|
||||
my @funclist = qw(
|
||||
xfs_alloc.c xfs_alloc_btree.c xfs_attr_leaf.c xfs_bit.c
|
||||
xfs_bmap.c xfs_bmap_btree.c xfs_btree.c xfs_da_btree.c
|
||||
xfs_dir.c xfs_dir2.c xfs_dir2_block.c xfs_dir2_data.c
|
||||
xfs_dir2_leaf.c xfs_dir2_node.c xfs_dir2_sf.c
|
||||
xfs_dir_leaf.c xfs_ialloc.c xfs_ialloc_btree.c
|
||||
xfs_inode.c xfs_rtalloc.c xfs_rtbit.c xfs_mount.c
|
||||
xfs_trans.c
|
||||
);
|
||||
|
||||
print "\n=== Checking libxfs code ===\n";
|
||||
foreach (@funclist) {
|
||||
functiondiff $_, 'cmd/xfs/libxfs', 'linux/fs/xfs';
|
||||
}
|
||||
print "\n=== Checking logprint code ===\n";
|
||||
functiondiff 'xfs_log_recover.c', 'cmd/xfs/logprint', 'linux/fs/xfs';
|
||||
@@ -0,0 +1,81 @@
|
||||
#!/bin/sh -x
|
||||
#
|
||||
# Simple script which does the following:
|
||||
# o Generates a src tarball from a WORKAREA
|
||||
# o Copies it over to ~/test and unpacks it
|
||||
# o Generates a src tarball from src tarball
|
||||
# o Compares the build status' ... reports problems
|
||||
# o removes ~/test
|
||||
#
|
||||
|
||||
tmpdir="$HOME/test"
|
||||
|
||||
if [ -z "$WORKAREA" ]
|
||||
then
|
||||
echo "WORKAREA is not set -- aborting."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -d $tmpdir ]
|
||||
then
|
||||
echo "$tmpdir exists already -- aborting."
|
||||
exit 1
|
||||
else
|
||||
mkdir $tmpdir
|
||||
if [ ! -d $tmpdir ]
|
||||
then
|
||||
echo "Cannot create $tmpdir -- aborting."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
#
|
||||
# Pleasantries are now out of the way, lets proceed.
|
||||
# NB: If something goes wrong we'll leave the unpacked
|
||||
# source alone for consumption by a human.
|
||||
#
|
||||
|
||||
_cleanup()
|
||||
{
|
||||
if [ $status -eq 0 ]
|
||||
then
|
||||
rm -fr $tmpdir
|
||||
else
|
||||
echo "Problem? -- leaving $tmpdir for inspection"
|
||||
fi
|
||||
}
|
||||
|
||||
_buildme()
|
||||
{
|
||||
cd $1
|
||||
|
||||
if ./Makepkgs
|
||||
then
|
||||
:
|
||||
else
|
||||
echo Makepkgs thinks theres a problem in $1
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f build/xfs-cmds-*.src.tar.gz ]
|
||||
then
|
||||
echo Makepkgs failed to create build/xfs-cmds-*.src.tar.gz
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
status=1
|
||||
trap "_cleanup; exit \$status" 0 1 2 3 15
|
||||
|
||||
# first, build from the WORKAREA
|
||||
_buildme $WORKAREA/cmd/xfs
|
||||
|
||||
cp $WORKAREA/cmd/xfs/build/xfs-cmds-*.src.tar.gz $tmpdir
|
||||
cd $tmpdir
|
||||
tar xzf xfs-cmds-*.src.tar.gz
|
||||
rm xfs-cmds-*.src.tar.gz # must delete for _buildme "cd" to work
|
||||
|
||||
# now, cross check the src build
|
||||
_buildme $tmpdir/xfs-cmds-*
|
||||
|
||||
status=0
|
||||
Reference in New Issue
Block a user