You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
292 lines
6.4 KiB
292 lines
6.4 KiB
#!/bin/bash
|
|
#######################################
|
|
# Inspiration from bug #34921
|
|
# Thanks to Paul Varner
|
|
|
|
# Distributed under the GPL v2
|
|
# Written by John Mylchreest (johnm@gentoo.org)
|
|
# Copyright Gentoo Linux
|
|
|
|
if [[ `id -u` != 0 ]]; then
|
|
echo "This application must be ran as root."
|
|
exit 1
|
|
fi
|
|
|
|
R_VERSION="0.5"
|
|
R_MODULES="${ROOT}/var/lib/module-rebuild/moduledb"
|
|
R_PORTAGEQ="`which portageq 2>/dev/null`"
|
|
if [[ -z ${R_PORTAGEQ} ]]; then
|
|
echo "** FATAL: Unable to find portageq."
|
|
exit 1
|
|
fi
|
|
R_PORTDIR=`${R_PORTAGEQ} portdir`
|
|
R_VDBPATH=`${R_PORTAGEQ} vdb_path`
|
|
R_OPTION_X=0;
|
|
R_OPTION_C=0;
|
|
|
|
package_valid() {
|
|
local package=${1}
|
|
[[ -z ${package} ]] && return 1
|
|
[[ -z ${package/*\/*} ]] && return 0 || return 1
|
|
}
|
|
|
|
package_valid_strict() {
|
|
local package=${1}
|
|
package_valid ${package} && [[ -z ${package%%*-[0-9]*} ]] && return 0 || return 1
|
|
}
|
|
|
|
package_exists() {
|
|
local package=${1}
|
|
|
|
package=${package%-[0-9]*}
|
|
if $(${R_PORTAGEQ} has_version / ${package}); then
|
|
return 0
|
|
else
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
db_module_exists() {
|
|
local line package=${1}
|
|
|
|
for line in `<${R_MODULES}`; do
|
|
[[ -z ${line/*${package}*} ]] && return 0
|
|
done
|
|
return 1
|
|
}
|
|
|
|
db_module_toggle() {
|
|
local package=${1} toggleto=${2} togglefrom line
|
|
|
|
if db_module_exists ${package}; then
|
|
line=`grep ${package} ${R_MODULES}`
|
|
togglefrom=${line#*:}
|
|
togglefrom=${togglefrom/:*}
|
|
if [[ -z ${toggleto} ]]; then
|
|
[[ ${togglefrom} = 0 ]] && toggleto=1 || toggleto=0
|
|
fi
|
|
echo "** Setting ${package}; rebuild=${toggleto}."
|
|
sed -i -e "s:\(.\:\)\([01]\)\(\:${package}\):\1${toggleto}\3:g" ${R_MODULES}
|
|
else
|
|
echo "** ${package} not found in moduledb."
|
|
fi
|
|
}
|
|
|
|
db_module_add() {
|
|
local package=${1}
|
|
|
|
if db_module_exists ${package}; then
|
|
echo -e "${C_BOLD}** Module already exists in moduledb.${C_NORM}"
|
|
db_module_toggle ${package} 1
|
|
return 0
|
|
else
|
|
if package_exists ${package}; then
|
|
echo -e "${C_BOLD}${C_GREEN}** Adding ${package} to moduledb.${C_NORM}"
|
|
echo "m:1:${package}" >> ${R_MODULES}
|
|
return 0
|
|
else
|
|
echo -e "${C_RED}** Unable to locate an available ebuild for ${package}.${C_NORM}"
|
|
echo "** Please manually emerge ${package} first."
|
|
fi
|
|
fi
|
|
return 1
|
|
}
|
|
|
|
db_module_del() {
|
|
local package=${1}
|
|
|
|
if db_module_exists ${package}; then
|
|
echo "** Removing ${package} from moduledb."
|
|
sed -ie "/.*${package/\//\\/}.*/d" ${R_MODULES}
|
|
return 0
|
|
else
|
|
echo "** ${package} not found in moduledb."
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
db_module_list() {
|
|
local line auto pkg a=0 b=0
|
|
|
|
for line in `<${R_MODULES}`; do
|
|
mode=${line:0:1}
|
|
pkg=${line#*:}
|
|
auto=${pkg/:*}
|
|
pkg=${pkg/*:}
|
|
|
|
if [[ ${R_OPTION_X} == 1 ]]; then
|
|
pkg=${pkg%-[0-9]*}
|
|
package_valid ${pkg}
|
|
else
|
|
package_valid_strict ${pkg} && pkg="=${pkg}"
|
|
fi
|
|
|
|
if [[ ${auto} = 1 ]]; then
|
|
tomerge[${a}]=${pkg}
|
|
a=$((${a} + 1))
|
|
else
|
|
toignore[${b}]=${pkg}
|
|
b=$((${b} + 1))
|
|
fi
|
|
done
|
|
|
|
pkg="${tomerge[@]}${toignore[@]}"
|
|
if [[ -z ${pkg} ]]; then
|
|
echo -e "${C_BOLD}${C_RED}** There are no known modules. Quitting.${C_NORM}"
|
|
exit 1
|
|
fi
|
|
|
|
if [[ -n ${tomerge[@]} ]]; then
|
|
echo -e "${C_BOLD}${C_GREEN}** Packages which I will emerge are:${C_NORM}"
|
|
for pkg in ${tomerge[@]}; do
|
|
echo -e "\t${pkg}"
|
|
done
|
|
fi
|
|
|
|
if [[ -n ${toignore[@]} ]]; then
|
|
echo -e "${C_BOLD}${C_GREEN}** Packages which I will ignore are:${C_NORM}"
|
|
for pkg in ${toignore[@]}; do
|
|
echo -e "\t${pkg}"
|
|
done
|
|
fi
|
|
}
|
|
|
|
db_module_populate() {
|
|
local i x=0 pkg version list pad
|
|
|
|
# Lets find them all
|
|
# chances are we will get a few dupes in here.
|
|
version=`uname -r`
|
|
for pkg in `grep -i /lib/modules/${version}/.*o ${R_VDBPATH}/*/*/CONTENTS`; do
|
|
pad=""; x=0;
|
|
|
|
if [[ -z ${pkg//${R_VDBPATH}*} ]]; then
|
|
for((i=0;i<=${#pkg};i++)); do
|
|
[[ ${pkg:${i}:1} = / ]] && x=$((${x} + 1));
|
|
[[ ${x} == 4 ]] || [[ ${x} == 5 ]] && pad="${pad}${pkg:${i}:1}";
|
|
done
|
|
# Remove any dupes
|
|
list=${list//${pad:1}}
|
|
list="${list} ${pad:1}"
|
|
fi
|
|
done
|
|
|
|
for pkg in ${list}; do
|
|
db_module_add ${pkg};
|
|
done
|
|
}
|
|
|
|
db_module_merge() {
|
|
local i pkg
|
|
|
|
echo -e "${C_BOLD}** Preparing to merge modules:${C_NORM}"
|
|
db_module_list >/dev/null
|
|
|
|
if [[ -z ${tomerge[@]} ]]; then
|
|
echo -e "${C_BOLD}${C_RED}** No packages to merge. Quitting.${C_NORM}"
|
|
exit 1
|
|
fi
|
|
|
|
echo -e "${C_BOLD}${C_GREEN}** Packages which I will emerge are:"${C_NORM}
|
|
for pkg in ${tomerge[@]}; do
|
|
echo -e "\t${pkg}"
|
|
done
|
|
|
|
for((i=1;i<6;i++)); do
|
|
echo -en "${C_BOLD}${C_RED}$((6 - ${i})) ${C_NORM}"
|
|
sleep 1
|
|
done
|
|
echo
|
|
|
|
emerge --oneshot --nodeps ${tomerge[@]}
|
|
}
|
|
|
|
phelp() {
|
|
cat << EOF
|
|
module-rebuild [options] action [category/package]
|
|
Version: ${R_VERSION}
|
|
|
|
Where options are:
|
|
-X - Emerge based on package names,
|
|
not exact versions.
|
|
-C - Disable all coloured output.
|
|
|
|
Where action is one of:
|
|
add - Add package to moduledb.
|
|
del - Delete a package from moduledb.
|
|
toggle - Toggle auto-rebuild of Package.
|
|
list - List packages to auto-rebuild.
|
|
rebuild - Rebuild packages.
|
|
populate - Populate the database with any
|
|
packages which currently install
|
|
drivers into the running kernel.
|
|
|
|
EOF
|
|
|
|
}
|
|
|
|
check_validity() {
|
|
local package=${1} strict=${2:-0} ret=1
|
|
|
|
[[ ${strict} = 0 ]] && package_valid ${package} && ret=0
|
|
[[ ${strict} = 1 ]] && package_valid_strict ${package} && ret=0
|
|
|
|
if [[ ${ret} != 0 ]]; then
|
|
echo "** Please pass the fully qualified package. For example:"
|
|
echo "** media-video/nvidia-kernel-1.0.7174"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
while getopts "XC" options; do
|
|
case ${options} in
|
|
X) R_OPTION_X='1';;
|
|
C) R_OPTION_C='1';;
|
|
*) phelp; exit 1;;
|
|
esac
|
|
done
|
|
|
|
if [[ ${R_OPTION_C} == 0 ]]; then
|
|
C_BOLD='\e[1m'
|
|
C_NORM='\e[0m'
|
|
C_GREEN='\e[32m'
|
|
C_RED='\e[31m'
|
|
else
|
|
C_BOLD=''
|
|
C_NORM=''
|
|
C_GREEN=''
|
|
C_RED=''
|
|
fi
|
|
|
|
x=0
|
|
for i in ${@:${OPTIND}}; do
|
|
if [[ ${i:0:1} != - ]]; then
|
|
R_PARAMS[${x}]=${i}
|
|
x=$((${x} + 1))
|
|
fi
|
|
done
|
|
unset i x
|
|
|
|
# If the moduledb doesnt exist, lets populate it automatically.
|
|
if [[ ! -f ${R_MODULES} ]]; then
|
|
echo -e "${C_BOLD}${C_RED}No moduledb found...${C_NORM}"
|
|
|
|
[[ ! -d ${ROOT}/var/lib/module-rebuild/ ]] && \
|
|
echo -e "${C_BOLD}Creating moduledb state directory.${C_NORM}"; \
|
|
mkdir -p ${ROOT}/var/lib/module-rebuild/
|
|
|
|
echo -e "${C_BOLD}Populating moduledb...${C_NORM}"
|
|
touch ${R_MODULES}
|
|
R_PARAMS[0]=populate
|
|
fi
|
|
|
|
case ${R_PARAMS[0]} in
|
|
add) check_validity ${R_PARAMS[1]} 1; db_module_add ${R_PARAMS[1]};;
|
|
del) check_validity ${R_PARAMS[1]}; db_module_del ${R_PARAMS[1]};;
|
|
toggle) check_validity ${R_PARAMS[1]}; db_module_toggle ${R_PARAMS[1]};;
|
|
list) db_module_list;;
|
|
rebuild) db_module_merge;;
|
|
populate) db_module_populate;;
|
|
*) phelp; exit 1;;
|
|
esac
|