- add netmap-libpcap
- add netmap (FreeBSD header files need to be updated with this) - move prototype perl scripts to prototype/ folder - create basic structure for sipcap app (no code yet)
This commit is contained in:
428
netmap/LINUX/scripts/np
Executable file
428
netmap/LINUX/scripts/np
Executable file
@ -0,0 +1,428 @@
|
||||
#!/bin/bash
|
||||
## Manage linux driver patches for netmap.
|
||||
## usage (from the dir containing the Makefile):
|
||||
##
|
||||
## scripts/np <action> [args...]
|
||||
##
|
||||
## where <action> is any of the functions below.
|
||||
##
|
||||
|
||||
[ -f scripts/conf ] && source scripts/conf
|
||||
|
||||
## The following enviroment variables must be set:
|
||||
##
|
||||
## GITDIR: the absolute path of the netmap linux
|
||||
## git repository, containing all the required netmap-*
|
||||
## branches.
|
||||
[ -n "$GITDIR" -a -d "$GITDIR/.git" ] || {
|
||||
echo "GITDIR not set or not valid" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
NETMAP_BRANCH=${NETMAP_BRANCH:-master}
|
||||
|
||||
function error {
|
||||
echo "$@" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
function get-params {
|
||||
local params=$1; shift
|
||||
err_msg="$PROGNAME $COMMAND $(echo $params| perl -pe 's/\S+/<$&>/g')"
|
||||
local param
|
||||
for param in $params; do
|
||||
[[ -z "$@" ]] && error "$err_msg"
|
||||
pname=$(echo -n $param | perl -pe 's/\W/_/g')
|
||||
eval $pname="$1"
|
||||
shift
|
||||
done
|
||||
[[ -n "$@" ]] && error "$err_msg"
|
||||
}
|
||||
|
||||
##
|
||||
## LINUX_SOURCES: the absolute path of a
|
||||
## directory used to store all required linux-* source trees
|
||||
## (The script will extract linux-x.y.z from GITDIR if it needs
|
||||
## it and $LINUX_SOURCES does not already contain it).
|
||||
##
|
||||
## LINUX_CONFIGS: the absolute path of a
|
||||
## directory containing the configuration files for
|
||||
## the linux kernel. The file for version x must be named
|
||||
## config-x. config-all can be used as a default.
|
||||
##
|
||||
## The configuration variables can be put in scripts/conf.
|
||||
##
|
||||
|
||||
##
|
||||
## Available actions:
|
||||
##
|
||||
|
||||
##
|
||||
## driver-path <driver> <version>
|
||||
## retrieves the path of <driver> in the linux sources
|
||||
## for version <version>. The path is output to stdout.
|
||||
## It uses a local cache to minimize the expensive
|
||||
## file system search.
|
||||
function driver-path()
|
||||
{
|
||||
get-params "driver version" "$@"
|
||||
|
||||
cat cache/$version/$driver/path 2>/dev/null && return
|
||||
local kern=$(get-kernel $version)
|
||||
mkdir -p cache/$version/$driver
|
||||
(
|
||||
cd $kern
|
||||
find drivers/net -name $driver
|
||||
) | tee cache/$version/$driver/path
|
||||
}
|
||||
|
||||
|
||||
##
|
||||
## get-patch [-c] <driver> <version>
|
||||
## extract the netmap patch for the given <driver> and the
|
||||
## given kernel <version>. The patch is stored in tmp-patches
|
||||
## and the name of the patch is output to stdout.
|
||||
## If a patch with the same name already exists in tmp-patches
|
||||
## it is overwritten, unless the -c option is used,
|
||||
## in which case the existing patch is kept (the patch name is still output).
|
||||
function get-patch()
|
||||
{
|
||||
local use_cache
|
||||
[ "$1" = -c ] && { use_cache=1; shift; }
|
||||
|
||||
get-params "driver version" "$@"
|
||||
|
||||
# convert kernel version to fixed notation
|
||||
local v1=$(scripts/vers $version -c)
|
||||
# compute next kernel version (in fixed notation)
|
||||
local v2=$(scripts/vers $version -i -c)
|
||||
local patchname=diff--$driver--$v1--$v2
|
||||
local out=tmp-patches/$patchname
|
||||
[ -n "$use_cache" -a -s $out ] && { echo $out; return; }
|
||||
local drvpath=$(driver-path $driver $version)
|
||||
[ -n "$drvpath" ] || return
|
||||
local drvdir=$(dirname $drvpath)
|
||||
(
|
||||
cd $GITDIR
|
||||
git diff --relative=$drvdir v$version..netmap-$version -- $drvpath
|
||||
) > $out
|
||||
# an empty patch means no netmap support for this driver
|
||||
[ -s $out ] || { rm $out; return 1; }
|
||||
echo $out
|
||||
return 0;
|
||||
}
|
||||
|
||||
##
|
||||
## get-range <driver> <version1> <version2>
|
||||
## extracts the netmap patches for the given <driver> for
|
||||
## all the kernel versions from <version1> (included) to
|
||||
## <version2> (excluded). All patches are stored in tmp-patches
|
||||
## and their names are output to stdout.
|
||||
function get-range()
|
||||
{
|
||||
get-params "driver version1 version2" "$@"
|
||||
|
||||
local v=$version1
|
||||
# while version is less than $version2
|
||||
while scripts/vers -b $v $version2 -L; do
|
||||
get-patch $driver $v
|
||||
# compute next version
|
||||
v=$(scripts/vers $v -i)
|
||||
done
|
||||
}
|
||||
|
||||
|
||||
##
|
||||
## get-src <driver> <version> <dest>
|
||||
## copies the original sources of the given <driver>,
|
||||
## from the given kernel <version> to the given <dest>
|
||||
## directory.
|
||||
## It uses a local cache to minimize the expensive
|
||||
## checkouts in GITDIR.
|
||||
function get-src()
|
||||
{
|
||||
get-params "driver version dest" "$@"
|
||||
|
||||
local kern=$(get-kernel $version)
|
||||
local src=$(driver-path $driver $version)
|
||||
cp -r $kern/$src $dest
|
||||
}
|
||||
|
||||
|
||||
##
|
||||
## extend <patch> <version>
|
||||
## checks wether the range of applicability of the
|
||||
## given <patch> can be extented to include <version>.
|
||||
## It returns 0 on success and 1 on failure.
|
||||
function extend()
|
||||
{
|
||||
get-params "patch version" "$@"
|
||||
|
||||
local _patch=$(realpath $patch)
|
||||
# extract the driver name from the patch name
|
||||
local driver=$(scripts/vers $_patch -s -p -p)
|
||||
local tmpdir1=$(mktemp -d)
|
||||
local tmpdir2=$(mktemp -d)
|
||||
trap "rm -rf $tmpdir1 $tmpdir2" 0
|
||||
# we get the driver sources for the given <version> and
|
||||
# we apply two patches separately:
|
||||
# i) the given <patch>;
|
||||
# ii) the proper patch from GITDIR.
|
||||
# We declare <patch> to be extendable if
|
||||
# - it is still applicable AND
|
||||
# - we obtain the same files from i) and ii) (ignoring whitespace)
|
||||
get-src $driver $version $tmpdir1
|
||||
get-src $driver $version $tmpdir2
|
||||
(
|
||||
cd $tmpdir1
|
||||
patch --no-backup-if-mismatch -p1 < $_patch >/dev/null 2>&1
|
||||
) || return 1
|
||||
local patch2=$(get-patch -c $driver $version)
|
||||
patch2=$(realpath $patch2)
|
||||
(
|
||||
cd $tmpdir2
|
||||
patch -p1 < $patch2 >/dev/null 2>&1
|
||||
) # this will certainly apply
|
||||
diff -qbBr $tmpdir1 $tmpdir2 >/dev/null || return 1
|
||||
return 0
|
||||
}
|
||||
|
||||
##
|
||||
## minimize <driver>
|
||||
## tries to minimize the number of patch files for the given
|
||||
## <driver>. It uses the patches currently found in tmp-patches
|
||||
## and stores the resulting patches in final-patches.
|
||||
## If final-patches already contained patches for <driver>,
|
||||
## they are deleted first.
|
||||
function minimize()
|
||||
{
|
||||
get-params "driver" "$@"
|
||||
|
||||
mkdir -p final-patches
|
||||
local drv=$(basename $driver)
|
||||
local patches=$(ls tmp-patches/diff--$drv--* 2>/dev/null)
|
||||
[ -n "$patches" ] || return 1
|
||||
# put the patch names in $1, $2, ...
|
||||
set $patches
|
||||
rm -f final-patches/diff--$drv--*
|
||||
# the original patches (in tmp-patches) are ordered by version number.
|
||||
# We consider one patch in turn (the 'pivot') and try
|
||||
# to extend its range to cover the range of the next
|
||||
# patch. If this succedes, the merged patch is the new
|
||||
# pivot, otherwise the current pivot is output and the
|
||||
# next patch becomes the new pivot. The process
|
||||
# is repeated until there are no more patches to consider.
|
||||
local pivot=$1
|
||||
[ -n "$pivot" -a -e "$pivot" ] || return 1
|
||||
# extract the left end and right end of the pivot's range
|
||||
local ple=$(scripts/vers $pivot -s -p -C)
|
||||
local pre=$(scripts/vers $pivot -s -C)
|
||||
while [ -n "$pivot" ]; do
|
||||
shift
|
||||
if [ -n "$1" ]; then
|
||||
# extract the left end and right end of the next patch
|
||||
local nle=$(scripts/vers $1 -s -p -C)
|
||||
local nre=$(scripts/vers $1 -s -C)
|
||||
# we admit no gaps in the range
|
||||
if [ $pre = $nle ] && extend $pivot $nle; then
|
||||
pre=$nre
|
||||
continue
|
||||
fi
|
||||
fi
|
||||
# either out of patches or failed merge.
|
||||
# Compute the file name of the current pivot and store
|
||||
# the patch in its final location
|
||||
out=$(scripts/vers diff $drv $ple -c $pre -c -S4)
|
||||
cp $pivot final-patches/$out
|
||||
# the new pivot becames the next patch (if any)
|
||||
pivot=$1
|
||||
pre=$nre
|
||||
ple=$nle
|
||||
done
|
||||
return 0
|
||||
}
|
||||
|
||||
##
|
||||
## infty <driver> <version>
|
||||
## if final-patches contains a patch for <driver> with a range
|
||||
## ending in <version>, extend it to infinity.
|
||||
## Do nothing otherwise.
|
||||
function infty()
|
||||
{
|
||||
get-params "driver version" "$@"
|
||||
|
||||
local drv=$(basename $driver)
|
||||
# convert kernel version to fixed notation
|
||||
local v=$(scripts/vers $version -c)
|
||||
local last=$(ls final-patches/diff--$drv--*--$v 2>/dev/null|tail -n1)
|
||||
[ -n "$last" ] || return 1
|
||||
mv -n $last $(scripts/vers $last -s -p 99999 -S4) 2>/dev/null
|
||||
}
|
||||
|
||||
function get-kernel()
|
||||
{
|
||||
get-params "version" "$@"
|
||||
|
||||
local dst="$(realpath $LINUX_SOURCES)/linux-$version"
|
||||
|
||||
[ -d $dst ] && { echo $dst; return; }
|
||||
|
||||
mkdir -p $dst
|
||||
|
||||
(
|
||||
cd $GITDIR
|
||||
git archive v$v | tar xf - -C $dst
|
||||
)
|
||||
echo $dst
|
||||
}
|
||||
|
||||
|
||||
##
|
||||
## build-prep <version>
|
||||
## prepare the linux tree for <version> to be ready
|
||||
## for external modules compilation.
|
||||
## The tree is put in $LINUX_SOURCES/linux-<version> and the
|
||||
## configuration is obtained from $LINUX_CONFIGS/config-<version>
|
||||
## (or $LINUX_CONFIGS/config-all by default).
|
||||
## Errors are logged to $LINUX_CONFIGS/linux-<version>.log.
|
||||
## If $LINUX_SOURCES/linux-<version> already exists,
|
||||
## nothing is done.
|
||||
## In all cases, the absolute path of linux-<version> is
|
||||
## output.
|
||||
function build-prep()
|
||||
{
|
||||
get-params "version" "$@"
|
||||
|
||||
local dst=$(get-kernel $version)
|
||||
|
||||
exec 3>&1 4>&2 >$dst.log 2>&1
|
||||
cp $LINUX_CONFIGS/config-$v $dst/.config 2>/dev/null ||
|
||||
cp $LINUX_CONFIGS/config-all $dst/.config
|
||||
(
|
||||
cd $dst
|
||||
yes '' | make oldconfig
|
||||
make modules_prepare
|
||||
)
|
||||
exec 1>&3 2>&4
|
||||
echo $dst
|
||||
}
|
||||
|
||||
##
|
||||
## check-patch <patch>
|
||||
## check that the given <patch> applies and compiles without
|
||||
## error for all its declared range of applicability.
|
||||
## Errors are logged to log/<patch>.
|
||||
function check-patch()
|
||||
{
|
||||
get-params "patch" "$@"
|
||||
|
||||
# extract the left version
|
||||
local v1=$(scripts/vers $patch -s -p -C)
|
||||
# extract the right version
|
||||
local v2=$(scripts/vers $patch -s -C)
|
||||
# extract the driver name
|
||||
local driver=$(scripts/vers $patch -s -p -p)
|
||||
local p=$(realpath $patch)
|
||||
mkdir -p log
|
||||
local log="$(realpath log)/$(basename $patch)"
|
||||
local nmcommit=$(cd ..; git show-ref -s heads/$NETMAP_BRANCH)
|
||||
|
||||
echo -n $patch...
|
||||
|
||||
while scripts/vers -b $v1 $v2 -L; do
|
||||
# cache lookup
|
||||
local cache=cache/$v1/$driver
|
||||
local cpatch=$cache/patch
|
||||
local cnmcommit=$cache/nmcommit
|
||||
local cstatus=$cache/status
|
||||
local clog=$cache/log
|
||||
if [ -f $cpatch ] &&
|
||||
cmp -s $cpatch $patch &&
|
||||
[ "$nmcommit" = "$(cat $cnmcommit)" ]; then
|
||||
cp $clog $log
|
||||
ok=$(cat $cstatus)
|
||||
else
|
||||
# update cache
|
||||
cp $patch $cpatch
|
||||
echo $nmcommit > $cnmcommit
|
||||
|
||||
local ksrc=$(build-prep $v1)
|
||||
local tmpdir=$(mktemp -d)
|
||||
trap "rm -rf $tmpdir" 0
|
||||
(cd ..; git archive $NETMAP_BRANCH | tar xf - -C $tmpdir )
|
||||
pushd $tmpdir/LINUX >/dev/null
|
||||
mkdir single-patch
|
||||
rm patches
|
||||
ln -s single-patch patches
|
||||
cp $p single-patch
|
||||
ok=false
|
||||
make KSRC=$ksrc >$log 2>&1 && ok=true
|
||||
popd >/dev/null
|
||||
cp $log $clog
|
||||
fi
|
||||
[ $ok = true ] || { echo FAILED; echo false > $cstatus; return 1; }
|
||||
echo true > $cstatus
|
||||
rm -rf $tmpdir
|
||||
# compute next version
|
||||
v1=$(scripts/vers $v1 -i)
|
||||
done
|
||||
echo OK
|
||||
}
|
||||
|
||||
##
|
||||
## build-check <driver>
|
||||
## do a check-patch for all the patches of <driver> that are
|
||||
## currently in tmp-patches. Patches that fail the check
|
||||
## are moved to failed-patches.
|
||||
function build-check()
|
||||
{
|
||||
get-params "driver" "$@"
|
||||
|
||||
mkdir -p failed-patches
|
||||
local drv=$(basename $driver)
|
||||
local patches=$(ls tmp-patches/diff--$drv--* 2>/dev/null)
|
||||
local p
|
||||
for p in $patches; do
|
||||
check-patch $p || mv $p failed-patches
|
||||
done
|
||||
}
|
||||
|
||||
##
|
||||
## forall <cmd> [args...]
|
||||
## exec <cmd> <driver> [args...] for all known drivers.
|
||||
function forall()
|
||||
{
|
||||
local cmd=$1
|
||||
shift
|
||||
# we obtain the value of DRIVER_SRC from the makefile
|
||||
# (the +% target is defined in our Makefile and prints
|
||||
# the contents of variable %)
|
||||
local driver_srcs=$(make +DRIVER_SRCS)
|
||||
|
||||
local driver
|
||||
for driver in $driver_srcs; do
|
||||
$cmd $(basename $driver) "$@"
|
||||
done
|
||||
}
|
||||
|
||||
mkdir -p tmp-patches
|
||||
|
||||
PROGNAME=$0
|
||||
|
||||
[ -n "$1" ] || {
|
||||
scripts/help $PROGNAME;
|
||||
exit 1
|
||||
}
|
||||
|
||||
COMMAND=$1; shift
|
||||
case $COMMAND in
|
||||
*-all)
|
||||
forall ${COMMAND%-all} "$@"
|
||||
;;
|
||||
-[hH]|--help|-help|help)
|
||||
scripts/help $PROGNAME
|
||||
;;
|
||||
*)
|
||||
$COMMAND "$@"
|
||||
;;
|
||||
esac
|
Reference in New Issue
Block a user