1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189
|
#!/bin/sh -e
# SPDX-License-Identifier: BSD-3-Clause
# Copyright (c) 2024 Red Hat, Inc.
#
# Import and check Linux Kernel uAPI headers
#
base_url="https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/plain/include/uapi/"
base_path="kernel/linux/uapi/"
version=""
file=""
check_headers=false
quiet=false
print_usage()
{
echo "Usage: $(basename $0) [-h] [-i FILE] [-u VERSION] [-c] [-q]"
echo "-i FILE import Linux header file. E.g. linux/vfio.h"
echo "-u VERSION update imported list of Linux headers to a given version. E.g. v6.10"
echo "-c check headers are valid"
echo "-q quiet mode"
}
version_older_than() {
printf '%s\n%s' "$1" "$2" | sort -C -V
}
download_header()
{
local header=$1
local path=$2
local url="$base_url$header?h=$version"
if ! curl -s -f --create-dirs -o $path $url; then
echo "Failed to download $url"
return 1
fi
return 0
}
update_headers()
{
local header
$quiet || echo "Updating to $version"
for filename in $(find $base_path -name "*.h" -type f); do
header=${filename#$base_path}
download_header $header $filename
done
return 0
}
import_header()
{
local include
local import
local header=$1
local path="$base_path$header"
download_header $header $path
for include in $(sed -ne 's/^#include <\(.*\)>$/\1/p' $path); do
if [ ! -f "$base_path$include" ]; then
read -p "Import $include (y/n): " import && [ "$import" = 'y' ] || continue
$quiet || echo "Importing $include for $path"
import_header "$include"
fi
done
return 0
}
fixup_includes()
{
local path=$1
sed -i "s|^#include <linux/compiler.h>||g" $path
sed -i "s|\<__user[[:space:]]||" $path
sed -i 's|#\(ifndef\)[[:space:]]*_UAPI|#\1 |' $path
sed -i 's|#\(define\)[[:space:]]*_UAPI|#\1 |' $path
sed -i 's|#\(endif[[:space:]]*/[*]\)[[:space:]]*_UAPI|#\1 |' $path
# Prepend include path with "uapi/" if the header is imported
for include in $(sed -ne 's/^#include <\(.*\)>$/\1/p' $path); do
if [ -f "$base_path$include" ]; then
sed -i "s|$include|uapi/$include|g" $path
fi
done
}
update_all()
{
if [ -n "$version" ]; then
if version_older_than "$version" "$current_version"; then
$quiet || echo "Headers already up to date ($current_version >= $version)"
version=$current_version
else
update_headers
fi
else
$quiet || echo "Version not specified, using current version ($current_version)"
version=$current_version
fi
if [ -n "$file" ]; then
import_header $file
fi
for filename in $(find $base_path -name "*.h" -type f); do
fixup_includes $filename
done
echo $version > $base_path/version
}
check_header()
{
$quiet || echo -n "Checking $1... "
if ! diff -q $1 $2 >/dev/null; then
$quiet || echo "KO"
$quiet || diff -u $1 $2
return 1
else
$quiet || echo "OK"
fi
return 0
}
check_all()
{
local errors=0
tmpheader="$(mktemp -t dpdk.checkuapi.XXXXXX)"
trap "rm -f '$tmpheader'" INT
$quiet || echo "Checking imported headers for version $version"
for filename in $(find $base_path -name "*.h" -type f); do
header=${filename#$base_path}
download_header $header $tmpheader
fixup_includes $tmpheader
check_header $filename $tmpheader || errors=$((errors+1))
done
if [ $errors -ne 0 ] || ! $quiet; then
echo "$errors error(s) found in Linux uAPI"
fi
rm -f $tmpheader
trap - INT
return $errors
}
while getopts i:u:cqh opt ; do
case $opt in
i ) file=$OPTARG ;;
u ) version=$OPTARG ;;
c ) check_headers=true ;;
q ) quiet=true ;;
h ) print_usage ; exit 0 ;;
? ) print_usage ; exit 1 ;;
esac
done
shift $(($OPTIND - 1))
if [ $# -ne 0 ]; then
print_usage
exit 1
fi
if $check_headers && [ -n "$file" -o -n "$version" ]; then
echo "The option -c is incompatible with -i and -u"
exit 1
fi
cd $(dirname $0)/..
current_version=$(cat $base_path/version)
if $check_headers; then
version=$current_version
check_all
else
update_all
fi
|