Add --out and option and a help text
[opensuse:driver-check.git] / driver-check.sh
1 #!/bin/bash
2
3 VERSION="0.1"
4 MAINTAINER="Michal Marek <mmarek@suse.cz>"
5 USAGE="Usage: ${0##*/} [-o|--out output-file]"
6
7 errors=0
8 warnings=0
9
10 trap 'rm -rf "$tmp"' EXIT
11 tmp=$(mktemp -d)
12
13 rpm()
14 {
15         # rpm tends to send localized error messages to stdout :-(
16         LC_ALL=C command rpm "$@"
17 }
18
19 file_owner()
20 {
21         local f=$1
22
23         if (cd "$tmp/rpms"; grep -HFx "$f" *); then
24                 return
25         fi
26         rpm -qf "$f"
27 }
28
29 error()
30 {
31         echo "ERROR: $*"
32         let errors++
33 }
34
35 warning()
36 {
37         echo "warning: $*" >&2
38         let warnings++
39 }
40
41 check_kernel()
42 {
43         local kernel=$1
44
45         if ! rpm -q --qf '%{description}\n' "$kernel" | grep -q '^GIT '; then
46                 error "$kernel does not look like a SUSE kernel package (no commit id)"
47         fi
48         if ! rpm -q --qf '%{postin}\n' "$kernel" | grep -q 'weak-modules2'; then
49                 error "$kernel does not look like a SUSE kernel package (wrong %post script)"
50         fi
51 }
52
53 check_kmp()
54 {
55         local kmp=$1 prefix prev_krel krel path
56
57         if ! rpm -q --qf '%{postin}\n' "$kmp" | grep -q 'weak-modules2'; then
58                 error "$kmp does not look like a SUSE kernel module package (wrong %post)"
59         fi
60         exec 3< <(sed -rn 's:^(/lib/modules)?/([^/]*)/(.*\.ko)$:\1 \2 \3:p' \
61                 "$tmp/rpms/$kmp")
62         while read prefix krel path <&3; do
63                 if test "$prefix" != "/lib/modules"; then
64                         error "$kmp installs modules outside of /lib/modules"
65                         continue
66                 fi
67                 if test -z "$prev_krel"; then
68                         prev_krel=$krel
69                 elif test "$prev_krel" != "$krel"; then
70                         error "$kmp installs modules for multiple kernel versions"
71                 fi
72                 case "$path" in
73                 updates/* | extra/*)
74                         ;;
75                 weak-modules/*)
76                         error "$kmp installs modules in weak-updates/ instead of updates/ or extra/"
77                         ;;
78                 *)
79                         error "$kmp installs modules in an invalid directory"
80                         ;;
81                 esac
82
83         done
84
85 }
86
87 check_ko()
88 {
89         local ko=$1 kmp
90
91         case "$ko" in
92         */weak-updates/*)
93                 if test -L "$ko"; then
94                         return
95                 fi
96         esac
97         kmp=$(file_owner "$ko")
98         case "$kmp" in
99         kernel-* | *-kmp-*) ;;
100         *not\ owned\ by\ any\ package)
101                 error "$ko is not owned by any package" ;;
102         *)
103                 error "$ko is not packaged as a KMP" ;;
104         esac
105 }
106
107 options=$(getopt -n "${0##*/}" -o o:h --long out:,help -- "$@")
108 if test "$?" -ne 0; then
109         echo "$USAGE" >&2
110         exit 1
111 fi
112 eval set -- "$options"
113 logfile="driver-check-report.txt"
114 while :; do
115         case "$1" in
116         -o | --out)
117                 logfile="$2"
118                 shift 2
119                 ;;
120         -h | --help)
121                 echo "${0##*/} $VERSION"
122                 echo "$USAGE"
123                 echo
124                 echo "Please report bugs and enhancement requests to $MAINTAINER"
125                 exit 0
126                 ;;
127         --)
128                 shift
129                 break
130                 ;;
131         esac
132 done
133 if test $# -gt 0; then
134         echo "Unrecognized arguments: $*" >&2
135         echo "$USAGE" >&2
136         exit 1
137 fi
138
139 # set up redirection
140 if test $logfile != "-"; then
141         if test -e "$logfile"; then
142                 mv -f "$logfile" "$logfile~"
143         fi
144         if test -e /proc/self; then
145                 exec 99> >(cat >"$logfile")
146                 exec 1>&99
147                 exec 2> >(tee -a /proc/self/fd/99 >&2)
148         else
149                 exec 1>"$logfile"
150                 exec 2>"$logfile"
151                 warning "/proc not mounted"
152         fi
153 fi
154 echo "${0##*/} started at $(date -R)" >&2
155
156 mkdir -p "$tmp/rpms"
157 found_kernel=false
158 for rpm in $(rpm -qa --qf '%{n}-%{v}-%{r}\n' 'kernel-*' '*-kmp-*' | \
159                 /usr/lib/rpm/rpmsort); do
160         case "$rpm" in
161         kernel-source-* | kernel-syms-* )
162                 continue
163         esac
164         # store the filelist to speed up file_owner()
165         rpm -ql "$rpm" >"$tmp/rpms/$rpm"
166         case "$rpm" in
167         kernel-*)
168                 check_kernel "$rpm"
169                 found_kernel=true
170                 ;;
171         *-kmp-*)
172                 check_kmp "$rpm"
173                 ;;
174         esac
175 done
176 if ! $found_kernel; then
177         warning "no kernel package found"
178 fi
179
180 kmps=($(find /lib/modules/ -name '*.ko'))
181 for kmp in "${kmps[@]}"; do
182         check_ko "$kmp"
183 done
184
185 echo "Found $errors error(s) and $warnings warning(s)" >&2
186 if test "$logfile" != -; then
187         echo "Report written to $logfile at $(date -R)" >&2
188 else
189         echo "Report finished at $(date -R)" >&2
190 fi
191 if test $errors -eq 0; then
192         exit 0
193 else
194         exit 1
195 fi