blob: a07722ac060a1d90c4591fd55cb662e16e71c4ef (
plain)
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
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
|
#!/bin/sh
# load the dracut libs
command -v getarg >/dev/null || . /lib/dracut-lib.sh
. /lib/url-lib.sh
# load the anaconda lib
. /lib/anaconda-lib.sh
# check if the DUD has the proper signature file
# and contains rpms for the given architecture
function dud_check()
{
localdud=$1
arch=$2
[ -e "$localdud/rhdd3" -a -e "$localdud/rpms/$arch" ];
}
# copy the rpm repository to RAM so we can eject the media
function dud_copy()
{
localdud=$1
arch=$2
dest=$3
cp -ar "$localdud/rpms/$arch" "$dest"
}
#dud_contents <driverdisc> <arch> <kernel> <anaconda>
function dud_contents()
{
local KERNEL=${3:-`uname -r`}
local ANACONDA=${4:-"master"}
local ARCH=${2:-`uname -m`}
local localdud=$1
"/bin/dud_list" -k "$KERNEL" -a "$ANACONDA" -d "$localdud"
}
# filter the driver update list so only the modules
# meant for instalation are in it
# TODO 7.1 there is no implementation of the rule mechanism atm.
function dud_rules()
{
cat
}
# extract driver update rpms selected for installation
# the list is passed using standard input
function dud_extract_all()
{
local repo=$1
local dest=$2
local rpm
local arg
local args
local extract_args
read rpm args
while [ "x$rpm" != "x" ]; do
echo "Extracting driver update rpm $rpm"
extract_args=""
for arg in $args; do
extract_args="$extract_args --$arg"
done
mkdir -p "$dest"
pushd "$dest"
echo "/bin/dud_extract" $extract_args --rpm=$rpm --directory=.
"/bin/dud_extract" $extract_args --rpm=$rpm --directory=.
popd
read rpm args
done
}
# stdin -> input data
# dud_parse x|. (default value)
function dud_parse()
{
local default=$1
local DESCTMP
read L
while [ "x$L" != "x" ]; do
SELECTED+=("$default")
FILES+=("$L")
read L
MODULES+=("$L")
read L
FLAGS+=("$L")
read L
DESCTMP=""
while [ "x$L" != "x---" ]; do
DESCTMP="$DESCTMP\n$L"
read L
done
DESCRIPTIONS+=("$DESCTMP")
read L
done
}
# dud_select <title line> <input data> [<default value> [noninteractive]]
# This is the (non)interactive part of module selection,
# the user can select drivers to install using simple text interface
# The list of selected modules gets printed out to the 3rd filedes
function dud_select()
{
local MODULES=()
local FILES=()
local DESCRIPTIONS=()
local FLAGS=()
local SELECTED=()
local DEFAULT=${3:-"."}
local MODE=${4:-"interactive"}
local L
dud_parse $DEFAULT <$2
if [ $MODE == "interactive" ]; then
L="x"
else
L=""
fi
# TUI
while [ "x$L" != "x" -a ${#MODULES[*]} -gt 0 ]; do
# header
clear
echo $1
echo
for i in "${!FLAGS[@]}"; do
echo $i ${SELECTED[$i]} ${MODULES[$i]} #${FLAGS[$i]}
done
echo
echo -n "Please type a number of the package you want to select or unselect: "
read L
if [[ "$L" =~ ^[0-9]+$ ]]; then
if [ ${SELECTED["$L"]} == "x" ]; then
SELECTED[$L]="."
elif [ ${SELECTED["$L"]} == "." ]; then
SELECTED[$L]="x"
fi
fi
done
# print all selected drivers to the result descriptor (3)
for i in "${!FLAGS[@]}"; do
if [ ${SELECTED[$i]} == "x" ]; then
echo ${FILES[$i]} ${FLAGS[$i]} 1>&3
fi
done
}
# process potential DUD for a given architecture
function driverupdatedisc()
{
local device=$1
local arch=$2
local num=$3
local DUD
local MODE
local DEFAULT
echo "Checking Driver Update Disc $device..."
DUD="/media/dud"
mkdir -p "$DUD"
mount $device "$DUD" || return
dud_check "$DUD" $arch || umount /media/dud || return
dud_copy "$DUD" $arch /tmp/DD-$num
dud_contents /tmp/DD-$num >/tmp/dud_list.txt
if [ -e "$DUD/rhdd3.rules" ]; then
MODE="interactive"
DEFAULT="."
else
MODE="noninteractive"
DEFAULT="x"
fi
dud_select "Select DUP RPMs to install" /tmp/dud_list.txt $DEFAULT $MODE 3>/tmp/dud_extract.txt
# extract the module files
dud_extract_all /tmp/DD-$num /tmp/duds/DD-$num </tmp/dud_extract.txt
# copy modules and firmwares to the proper directories
# modules are in <kernel version>/{kernel,updates,extra}/* structure so
# strip the kernel version and the first directory name of it
mkdir -p "/lib/modules/$(uname -r)/updates/DD" "/lib/firmware/updates"
cp -r /tmp/duds/DD-$num/lib/modules/*/*/* "/lib/modules/$(uname -r)/updates/DD"
cp -r /tmp/duds/DD-$num/lib/firmware/* /lib/firmware/
# copy binaries and libraries to / directory
# TODO
# save the list of extracted modules for later use in anaconda
cat /tmp/dud_extract.txt >>/tmp/dud_extracted.txt
# TODO add DD-X as a Yum repository
# release the DUD
umount "$DUD"
# regenerate module lists
depmod -a
# get a list of modules that weren't loaded when this script started
cut -f1 -d " " /proc/modules >/tmp/dud_state_current
cat /tmp/dud_state /tmp/dud_state_current | sort | uniq -u >/tmp/dud_rmmod
# iterative removal of package dependencies
local REMOVING=1
# remove all modules that were added by driver updates and can be removed
while [ $REMOVING -gt 0 ]; do
# this might be the last iteration
REMOVING=0
for mod in $(cat /tmp/dud_rmmod); do
rmmod $mod 2>/dev/null
if [ $? -eq 0 ]; then
# is something was removed, there needs to be another iteration
# to remove the modules that depended on this one
echo "Module $mod removed"
REMOVING=1
fi
done
done
# wait a bit to let the kernel and udev stabilize
sleep 1
# load modules (in their new version incarnation) again
udevadm trigger
}
#
# The main flow of execution starts below this point
#
# save module state
cut -f1 -d " " /proc/modules >/tmp/dud_state
# get hw architecture
ARCH=$(uname -i)
# load all modules
udevadm trigger
# check all devices for the "oemdrv" label
DUDS=$(blkid -t LABEL=OEMDRV | cut -d: -f1)
NUM=0
# go through the detected devices
for dud in $DUDS; do
driverupdatedisc $dud $ARCH $NUM
NUM=$(expr $NUM + 1)
done
# manual driver selection
DD=$(getarg dd)
# TODO what if there are multiple dd= arguments?
if [ $? -eq 0 ]; then
# if dd or dd=<nonsense>, show UI
# else if dd=url, skip now, we will process it when network is ready
# else skip UI steps and use the argument as path to the image
# UI select device
# UI select partition (if there are any)
# UI browse directories (if rhdd3 file is present, skip following steps)
# UI select driver update disc image
driverupdatedisc $dud $ARCH $NUM # TODO skip mounting for directory based DUDs
NUM=$(expr $NUM + 1)
fi
|