From 1c75627fd516087ac36652081ed9f613e019c5ee Mon Sep 17 00:00:00 2001 From: CrazyCat Date: Wed, 7 Apr 2021 19:02:17 +0300 Subject: [PATCH] DKMS helper files. --- 00_opt_default.inc | 15 +++ Makefile.dkms | 22 ++++ README_dkms | 94 ++++++++++++++ build_all.sh | 255 ++++++++++++++++++++++++++++++++++++ create_dkms_tar.sh | 28 ++++ dkms.conf | 63 +++++++++ dkms_updated_modules.conf | 22 ++++ dkms_ver.conf | 1 + gen_dkms_dyn_conf.sh | 150 +++++++++++++++++++++ handle_updated_modules.sh | 267 ++++++++++++++++++++++++++++++++++++++ install.sh | 2 +- 11 files changed, 918 insertions(+), 1 deletion(-) create mode 100644 00_opt_default.inc create mode 100644 Makefile.dkms create mode 100644 README_dkms create mode 100755 build_all.sh create mode 100755 create_dkms_tar.sh create mode 100644 dkms.conf create mode 100644 dkms_updated_modules.conf create mode 100644 dkms_ver.conf create mode 100755 gen_dkms_dyn_conf.sh create mode 100755 handle_updated_modules.sh diff --git a/00_opt_default.inc b/00_opt_default.inc new file mode 100644 index 0000000..911adda --- /dev/null +++ b/00_opt_default.inc @@ -0,0 +1,15 @@ +# With VDR this gives tons of loggings +disable_opt CONFIG_DVB_DEMUX_SECTION_LOSS_LOG + +# builds fine with this drivers, but keep them for later +#disable_opt CONFIG_VIDEOBUF2_MEMOPS + +# CONFIG_FRAME_VECTOR causes troubles on some systems/distros +disable_opt CONFIG_FRAME_VECTOR + +# MSI is currently still not reliable on Digital Devices cards +disable_opt CONFIG_DVB_DDBRIDGE_MSIENABLE + +# There are systems with more high end Digital Devices cards with lots +# of tuners +set_opt_value CONFIG_DVB_MAX_ADAPTERS 64 diff --git a/Makefile.dkms b/Makefile.dkms new file mode 100644 index 0000000..2144cce --- /dev/null +++ b/Makefile.dkms @@ -0,0 +1,22 @@ +# +# Will be executed by the DKMS system, with +# KERNELRELEASE and MEDIA_INST_DIR +# set. +# + +ifneq ($(MAKECMDGOALS),clean) + ifeq ($(KERNELRELEASE),) + $(error KERNELRELEASE not set) + endif +endif +ifeq ($(MEDIA_INST_DIR),) + $(error MEDIA_INST_DIR not set) +endif + +build: + VER=$(KERNELRELEASE) ./build_all.sh $(MEDIA_INST_DIR) -db + +clean: + VER=$(KERNELRELEASE) ./build_all.sh $(MEDIA_INST_DIR) -dc + +.PHONY: build clean diff --git a/README_dkms b/README_dkms new file mode 100644 index 0000000..95e6e47 --- /dev/null +++ b/README_dkms @@ -0,0 +1,94 @@ + + DKMS support description + +This file describes how to create a media-build DKMS package. + +This branch of media_build contains the scripts for the media_build DKMS +support. +It requires a media-tree to be used by the resulting DKMS package. In principle +the DKMS support scripts can use any existing media-tree and use it. To get +reproducable results for distributions, we need a stable media-tree. Thus +there are branches available in + https://github.com/jasmin-j/dddvb-linux-kernel +See below for details about the branch naming in linux-media. + + +First checkout the branch you want to create a DKMS from. + +Then create the "linux-media.tar.bz2" archive out of the existing Kernel +tree. This can be easily done by: + ./build_all.sh -dt + needs to point to your linux-media tree. + + +Now we need to define the version of the DKMS package. This can be easily +done in "dkms_ver.conf". The version number can be any number required for +the distribution you make the DKMS package for. +Keep in mind, that also media_build needs to match the kernel source tree +due to the backport patches, which need to match the Kernel sources. So +the number should reflect the combination of media-tree and media-build. + +Because each new version of linux-media requires also a new version of +media_build (due to the changed "dkms_ver.conf" file), I recomend to use +simply a counting number. + +Now you can test your package (you may skip that). +Use + $ sudo dkms add . +to add the current directory to the DKMS system. + + $ sudo dkms build media_build/ +will compile all the enabled modules for the currently running kernel. + + $ sudo dkms build media_build/ -k +will compile all the enabled modules for the given Kernel version. + + $ sudo dkms remove media_build/ -k | --all +will remove the current directory from the DKMS system + + +Just above is stated "all the enabled modules". There is a simple method to +en/disable drivers. +The files "??_any_name.inc" are included by "build_all.sh" and can be used to +set/clear Kernel options and parameters. This is intended for distributions +which may add new files according to their needs. + + +The Debian DKMS tree on + https://github.com/jasmin-j/media_build_dkms +requires a tar file containing the DKMS and Kernel tree. For that the script +"create_dkms_tar.sh" is used. It creates + "media-build-.dkms_src.tgz +PACKAGE_VERSION is read from dkms_ver.conf, so you need to edit this file +prior to the tar file creation. + +The created tar file can be now used together with the above mentioned Debian +DKMS tree or with a similar packager. + + + + DKMS Branch naming in linux-media + +The mediatree/master-ddbridge branch is used as the integration branch for +improvements and bugfixes. It is constantly rebased to mediatree/master and +therefore the HASHes are rewritten. + +With this approach it is not possible to make valid TAGs. On the other hand +keeping mediatree/master-ddbridge consistant is too much effort. So we need +stable branches as snapshots. + +The snapshots branch names have to start with "dkms/" followed by a number +which gets incremented with each new snapshot and finaly the date of the +snapshot generation. The latter is required, because the commit dates are +not suffcient to know when the snapshot has been taken. + +Examples: + dkms/0001-19_Aug_2017 + dkms/0002-28_Aug_2017 + dkms/0003-29_Aug_2017 + +media-build uses the same branch naming. It may happen that media-build +requires an update due to improofments. In that case the number from +media-build might be higher than the one from linux-media. With the next +change at linux-media this will be egalized. + diff --git a/build_all.sh b/build_all.sh new file mode 100755 index 0000000..784c2f8 --- /dev/null +++ b/build_all.sh @@ -0,0 +1,255 @@ +#!/bin/bash + +function usage { + echo "Usage: $0 [-l][-v][-c][-db][-dc][-dt][--help]" + echo " -c ... clean" + echo " -l ... make linux" + echo " -v ... make v4l" + echo " -db .. DKMS build" + echo " -dc .. DKMS clean" + echo " -dt .. DKMS TAR" + echo " Note: If -l and -v are not present, both are executed." + echo " The order of the options needs to be as written above!" + echo " If -db or -dc are present, -c, -l and -v are ignored and" + echo " is used as the installation path." + echo " If -dt is present, all other options are ignored. This will" + echo " do implicite -c and then create the TAR archive." + exit 1 +} + +function disable_opt { + echo Disabling ${1} + sed -i \ + -e s/${1}=[y\|m]/#\ ${1}\ is\ not\ set/ \ + v4l/.config +} + +function set_opt_y { + echo Enabling Y ${1} + sed -i \ + -e s/#\ ${1}\ is\ not\ set/${1}=y/ \ + v4l/.config +} + +function set_opt_m { + echo Enabling M ${1} + sed -i \ + -e s/#\ ${1}\ is\ not\ set/${1}=m/ \ + v4l/.config +} + +function set_opt_value { + echo Setting ${1} to ${2} + sed -i \ + -e s/${1}=.*/${1}=${2}/ \ + v4l/.config +} + +function make_linux { + cd linux + + if [ "${do_clean}" = "y" ] ; then + make ${linux_clean} + # mm remains, should be reportded to media_build maintainers + rm -rf mm + + if [ "${do_tar}" == "y" ] ; then + make tar DIR=../${1} + rm -f git_log + rm -f kernel_version.h + fi + else + if [ "${do_dkms}" != "y" ] ; then + make tar DIR=../${1} + fi + make untar + fi + + cd .. +} + +function import_options { + # we need the list sorted according to the number prefix + inc_files=$(find . -name "*.inc" | sort -u) + if [ -n "${inc_files}" ] ; then + for incfile in ${inc_files} ; do + # we allow only the functions we define in this script + rm -f ${incfile}.tmp + sed -n -e '/^disable_opt/p' -e '/^set_opt_y/p' -e '/^set_opt_m/p' \ + -e '/^set_opt_value/p' ${incfile} > ${incfile}.tmp + source ${incfile}.tmp + rm ${incfile}.tmp + done + fi +} + +function make_v4l { + if [ "${do_clean}" = "y" ] ; then + make ${v4l_clean} + + if [ -d "${dkms_inst_dir}" -a "${do_dkms}" = "y" ] ; then + if [ -d "${dkms_inst_dir}" ] ; then + # additional security to be sure we remove the right directory + if [ -f "${dkms_inst_dir}/DKMS_INST" ] ; then + rm -rf ${dkms_inst_dir} + else + echo "Error: '${dkms_inst_dir}' is no DKMS install path!" + exit 4 + fi + fi + fi + else + make stagingconfig + + import_options + + make -j${job_num} + + if [ "${do_dkms}" = "y" ] ; then + if [ ! -d "${dkms_inst_dir}" ] ; then + make DESTDIR=${dkms_inst_dir} install + if [ $? -eq 0 ] ; then + # additional security to be sure we remove the right directory + # when cleaning (option -dc) + rm -rf ${dkms_inst_dir}/DKMS_INST + date -R > ${dkms_inst_dir}/DKMS_INST + fi + else + echo "Error: DKMS install path '${dkms_inst_dir}' already exists!" + exit 3 + fi + fi + fi +} + +if [ $# -lt 1 ] ; then + usage +fi + +# matches "--help" also +if [[ ${1} =~ ^-.* ]] ; then + usage +fi + +# determine num of available cores for make job control +nProc=$(getconf _NPROCESSORS_ONLN) +job_num=$(( nProc + 1 )) + +kernelsourcedir=${1} +shift + +linux_clean="distclean" +v4l_clean="distclean" +do_dkms="d" +do_linux="d" +do_v4l="d" +do_tar="d" + +# Some DKMS version might need to override jobs, so checking +# for an environment variable JOBS +if [ -n "${JOBS}" ] ; then + # JOBS need to be numeric + case ${JOBS} in + '' | *[!0-9]*) + echo "Error: ENV Variable 'JOBS' ins not numeric!" + exit 2 + ;; + esac + job_num=${JOBS} +fi + +if [ "${1}" = "-l" ] ; then + do_linux="y" + do_v4l="n" + shift +fi + +if [ "${1}" = "-v" ] ; then + do_v4l="y" + if [ "${do_linux}" = "d" ] ; then + do_linux="n" + fi + shift +fi + +if [ "${1}" = "-c" ] ; then + do_clean="y" + do_linux="d" + do_v4l="d" + shift +fi + +if [ "${1}" = "-db" ] ; then + do_clean="n" + do_linux="d" + do_v4l="d" + do_dkms="y" + dkms_inst_dir="${kernelsourcedir}" + shift +fi + +if [ "${1}" = "-dc" ] ; then + do_clean="y" + do_linux="d" + do_v4l="d" + # keep the linux tree tar.bz2 file + linux_clean="clean" + do_dkms="y" + dkms_inst_dir="${kernelsourcedir}" + shift +fi + +if [ "${1}" = "-dt" ] ; then + do_clean="y" + do_linux="d" + do_v4l="d" + do_dkms="d" + do_tar="y" + # default might be overridden already + linux_clean="distclean" + v4l_clean="distclean" + shift +fi + +# needs to be last +if [ "${1}" = "--help" ] ; then + usage +fi + +if [ $# -gt 0 ] ; then + usage +fi + +if [ "${do_dkms}" != "y" ] ; then + if [ ! -d ${kernelsourcedir} ] ; then + echo "Error: Kernel source dir '${kernelsourcedir}' does not exist!" + exit 5 + fi + + txt_body="for kernel sources at ${kernelsourcedir}" + txt_dkms="" +else + txt_body="with installation path ${kernelsourcedir}" + txt_dkms="DKMS: " +fi + +if [ "${do_clean}" != "y" ] ; then + txt_start="${txt_dkms}Running media build ${txt_body}" +else + txt_start="${txt_dkms}Cleaning media build" +fi + +echo "${txt_start}" + +if [ -n "${VER}" -a "${do_clean}" != "y" ] ; then + # generate first ./v4l/.version, which is used by all other scripts + make VER=${VER} release +fi + +if [ "${do_linux}" = "y" -o "${do_linux}" = "d" ] ; then + make_linux ${kernelsourcedir} +fi + +if [ "${do_v4l}" = "y" -o "${do_v4l}" = "d" ] ; then + make_v4l +fi diff --git a/create_dkms_tar.sh b/create_dkms_tar.sh new file mode 100755 index 0000000..87b8bc4 --- /dev/null +++ b/create_dkms_tar.sh @@ -0,0 +1,28 @@ +#!/bin/bash + +# get DKMS version to variable PACKAGE_VERSION +. dkms_ver.conf + +DKMS_TAR_NAME=media-build-${PACKAGE_VERSION}.dkms_src.tgz + +tar_dirs="backports " +tar_dirs+="devel_scripts " +tar_dirs+="linux " +tar_dirs+="v4l " + +tar_files="*.inc " +tar_files+="build_all.sh " +tar_files+="COPYING " +tar_files+="dkms.conf " +tar_files+="dkms_ver.conf " +tar_files+="gen_dkms_dyn_conf.sh " +tar_files+="INSTALL " +tar_files+="Makefile " +tar_files+="Makefile.dkms " +tar_files+="README_dkms " +tar_files+="handle_updated_modules.sh " +tar_files+="dkms_updated_modules.conf " + +rm -f ${DKMS_TAR_NAME} +tar -czf ${DKMS_TAR_NAME} ${tar_dirs} ${tar_files} + diff --git a/dkms.conf b/dkms.conf new file mode 100644 index 0000000..2f73d80 --- /dev/null +++ b/dkms.conf @@ -0,0 +1,63 @@ +PACKAGE_NAME=media-build + +# Source the media_build DKMS version definition +conf_dir=$(dirname ${BASH_SOURCE[0]}) +. ${conf_dir}/dkms_ver.conf + +[ -n "$module" ] || module=${PACKAGE_NAME} +[ -n "$module_version" ] || module_version=${PACKAGE_VERSION} + +# The base for the module +local dkms_dir="$dkms_tree/$module/$module_version" + +# This is where DKMS stores all of it's data (after the MAKE[0] step!). +local base_dir="$dkms_dir/$kernelver/$arch" + +# We need an existing path during the build step to create the install +# directory, because media build will also install all the modules. The +# install directory will be cleaned just after the POST_BUILD step, so +# this directory is existing very short on the file system. +local media_inst_dir="$dkms_dir/build/_media_inst" + +# The dynamically generated DKMS configuration file name. This gets sourced by +# the top DKMS configuration file (this file), if it exists (see end of this +# script). It defines all the built modules depending on the kernel version or +# configuration options of medial_build. +# +# This dynamically generated DKMS configuration file is generated by a post +# build command script (gen_dkms_dyn_conf.sh). +# +# It is important, that it exists when the DKMS install command is executed. +local dkms_dyn_conf="$base_dir/dkms_dyn.conf" + +# The module directory, where DKMS stores the built modules after the build. +local dkms_mod_dir="$base_dir/module" + +AUTOINSTALL=y + +# The DKMS system will add KERNELRELEASE to the make command line +MAKE[0]="make MEDIA_INST_DIR=$media_inst_dir -f Makefile.dkms build" +CLEAN="make MEDIA_INST_DIR=$media_inst_dir -f Makefile.dkms clean" +POST_BUILD="gen_dkms_dyn_conf.sh $dkms_mod_dir $media_inst_dir $dkms_dyn_conf" +#POST_INSTALL="handle_updated_modules.sh $base_dir $kernelver $arch install" +CHECK_MODULE_VERSION=n + +# There have to be at least one module defined in the top DKMS configuration +# file, otherwise DKMS throws an error. +# Note: This definition gets overridden later by the dynamically generated +# DKMS configuration file. +# +BUILT_MODULE_NAME[0]=dvb-core +# +# We use here the real build location, because the file needs to exist to +# finish the build step. +BUILT_MODULE_LOCATION[0]=./v4l +# +# It is important to use the real module path here, so that the uninstall +# command works correctly +DEST_MODULE_LOCATION[0]=/kernel/drivers/media/dvb-core + +# Source the dynamically generated DKMS configuration file. +if [ -e $dkms_dyn_conf ]; then + . $dkms_dyn_conf +fi diff --git a/dkms_updated_modules.conf b/dkms_updated_modules.conf new file mode 100644 index 0000000..386a589 --- /dev/null +++ b/dkms_updated_modules.conf @@ -0,0 +1,22 @@ +# +# List of modules to be removed after DKMS install. +# +# It is intended to list here modules, which may installed in the original +# Kernel tree, but should no longer be there because they are exchanged by +# other modules or no longer supported. +# +REMOVE_MODULE_NAME[0]=lirc_sasem +REMOVE_MODULE_LOCATION[0]=/kernel/drivers/staging/media/lirc +REMOVE_MODULE_NAME[1]=lirc_parallel +REMOVE_MODULE_LOCATION[1]=/kernel/drivers/staging/media/lirc +REMOVE_MODULE_NAME[2]=lirc_igorplugusb +REMOVE_MODULE_LOCATION[2]=/kernel/drivers/staging/media/lirc +REMOVE_MODULE_NAME[3]=lirc_bt829 +REMOVE_MODULE_LOCATION[3]=/kernel/drivers/staging/media/lirc +REMOVE_MODULE_NAME[4]=lirc_imon +REMOVE_MODULE_LOCATION[4]=/kernel/drivers/staging/media/lirc +REMOVE_MODULE_NAME[5]=lirc_sir +REMOVE_MODULE_LOCATION[5]=/kernel/drivers/staging/media/lirc +REMOVE_MODULE_NAME[6]=lirc_serial +REMOVE_MODULE_LOCATION[6]=/kernel/drivers/staging/media/lirc + diff --git a/dkms_ver.conf b/dkms_ver.conf new file mode 100644 index 0000000..e82f500 --- /dev/null +++ b/dkms_ver.conf @@ -0,0 +1 @@ +PACKAGE_VERSION=0001 diff --git a/gen_dkms_dyn_conf.sh b/gen_dkms_dyn_conf.sh new file mode 100755 index 0000000..7d4528a --- /dev/null +++ b/gen_dkms_dyn_conf.sh @@ -0,0 +1,150 @@ +#!/bin/bash + +# base for the final installation in "/lib/modules/..." (might be changed +# for different distributions) +# Note: DKMS handles most if the distribution specific part already! +mod_dest_loc_base="/kernel" + +# base where media build does install all the modules (defined by media +# build scripts; do not change!) +mod_build_loc_base='/kernel' + +# Valid dummy to be used for the build location (not used by DKMS) +mod_dir='./v4l' + +mod_pattern='*.ko' + + +err_ok=0 +err_usage=1 +err_dir_not_found=2 +err_default=10 + +# Index 0 is the dvb-core.ko module defined in the top DKMS +# configuration file. We override this default by the dynamically +# generated DKMS configuration. +mod_idx=0 + +module_copy_script_name="mod_copy.sh" +module_copy_script="${module_copy_script_name}" + +mod_build_loc="" + +function exit_print { + if [ -z "${2}" ] ; then + code=${err_default} + else + code=${2} + fi + + echo "${1}" + exit ${code} +} + +function err_exit { + exit_print "Error: ${1}" ${2} +} + +function usage { + echo "Usage: $0 [--help]" + echo " : directory where the modules are stored by" + echo " DKMS after the build step." + echo " : directory where the media build has installed all" + echo " the modules with their right location" + echo " : filename of the dynamic part of the DKMS config" + echo " file generated by this script." + echo " Options:" + echo " --help: This text" + exit_print "" ${err_usage} +} + +# Note: This function gets executed in a sub-shell (pipe in find_modules), +# so it is not possible to use mod_idx later! +function found_module { + mod_name=$(basename -s .ko ${1}) + mod_build_dir=$(dirname ${1}) + if [[ ${mod_build_dir} =~ (.*)${mod_build_loc_base}(.*) ]] ; then + mod_dest_location="${mod_dest_loc_base}${BASH_REMATCH[2]}" + echo "BUILT_MODULE_NAME[${mod_idx}]=${mod_name}" >> ${dkms_dyn_conf} + echo "BUILT_MODULE_LOCATION[${mod_idx}]=${mod_dir}" >> ${dkms_dyn_conf} + echo "DEST_MODULE_LOCATION[${mod_idx}]=${mod_dest_location}" >> ${dkms_dyn_conf} + + echo "cp -af ${mod_build_dir}/${mod_name}.ko ${module_dir}/${mod_name}.ko" >> ${module_copy_script} + + mod_idx=$((mod_idx + 1)) + fi +} + +function find_modules { + find ${mod_build_loc} -name ${mod_pattern} | while read file; do found_module "$file"; done +} + +function arg_check_help { + if [ "${1}" = "--help" ] ; then + usage + fi +} + +# main + +if [ $# -lt 3 ] ; then + usage +fi + +arg_check_help "${1}" + +module_dir="${1}" +shift + +arg_check_help "${1}" + +media_inst_dir="${1}" +shift + +arg_check_help "${1}" + +dkms_dyn_conf="${1}" +shift + +# First check, if the target module directory to store also the dynamically +# generated files, does already exist +if [ ! -d ${module_dir} ] ; then + err_exit "Target module directory ${module_dir} doesn't exist!" ${err_dir_not_found} +fi + +# Check if the media build has been installed the new modules +if [ ! -d ${media_inst_dir} -a -f "${media_inst_dir}/DKMS_INST" ] ; then + err_exit "Installed media build modules not found in ${media_inst_dir}!" ${err_dir_not_found} +fi + +# Now check, if the directory of the generated file +# does already exist +dkms_dyn_conf_dir=$(dirname ${dkms_dyn_conf}) +if [ ! -d ${dkms_dyn_conf_dir} ] ; then + err_exit "Target directory for dynamic DKMS config doesn't exist!" ${err_dir_not_found} +fi + +module_copy_script="${dkms_dyn_conf_dir}/${module_copy_script_name}" +mod_build_loc="${media_inst_dir}" + +# we generate it always new +rm -f ${dkms_dyn_conf} +echo "#" > ${dkms_dyn_conf} +echo "# Generated by $(basename ${0})" >> ${dkms_dyn_conf} +echo "# at $(date -R)" >> ${dkms_dyn_conf} +echo "#" >> ${dkms_dyn_conf} + +rm -f ${module_copy_script} +echo "#!/bin/bash" > ${module_copy_script} +echo "#" >> ${module_copy_script} +echo "# Generated by $(basename ${0})" >> ${module_copy_script} +echo "# at $(date -R)" >> ${module_copy_script} +echo "#" >> ${module_copy_script} + +find_modules + +# copy the generated modules +source ${module_copy_script} + +exit_print "Done!" ${err_ok} + diff --git a/handle_updated_modules.sh b/handle_updated_modules.sh new file mode 100755 index 0000000..b55f6bb --- /dev/null +++ b/handle_updated_modules.sh @@ -0,0 +1,267 @@ +#!/bin/bash + +# base for the final installation in "/lib/modules/..." (might be changed +# for different distributions) +# Note: DKMS handles most if the distribution specific part already! +mod_dest_loc_base="/kernel" + +upd_mod_conf_name='dkms_updated_modules.conf' +mod_pattern='*.ko' +module_suffix='.ko' +install_tree="/lib/modules" + + +err_ok=0 +err_usage=1 +err_dir_not_found=2 +err_tmp_failed=3 +err_read_config=4 +err_kernel_tree=5 +err_action=6 +err_default=20 + +modules_removed="" + +readonly update_conf_variables="REMOVE_MODULE_NAME REMOVE_MODULE_LOCATION" + +function exit_print { + if [ -z "${2}" ] ; then + code=${err_default} + else + code=${2} + fi + + echo "${1}" + exit ${code} +} + +function err_exit { + exit_print "Error: ${1}" ${2} +} + +function usage { + echo "Usage: $0 [--help]" + echo " : directory where the DKMS stores the build information" + echo " (there are the 'module' and 'log' directories)." + echo " : kernel version as used by DKMS" + echo " : architecture as used by DKMS" + echo " : install or uninstall" + echo " Options:" + echo " --help: This text" + exit_print "" ${err_usage} +} + +function arg_check_help { + if [ "${1}" = "--help" ] ; then + usage + fi +} + +mktemp_or_die() { + local t + t=$(mktemp "$@") && echo "$t" && return + [[ $* = *-d* ]] && err_exit "Unable to make temporary directory" ${err_tmp_failed} + err_exit "Unable to make temporary file." ${err_tmp_failed} +} + +# copied from dkms shell script +function safe_source { + # $1 = file to source + # $@ = environment variables to echo out + local to_source_file="$1"; shift + declare -a -r export_envs=("$@") + local tmpfile=$(mktemp_or_die) + ( exec >"$tmpfile" + . "$to_source_file" >/dev/null + # This is really ugly, but a neat hack + # Remember, in bash 2.0 and greater all variables are really arrays. + for _export_env in "${export_envs[@]}"; do + for _i in $(eval echo \${!$_export_env[@]}); do + eval echo '$_export_env[$_i]=\"${'$_export_env'[$_i]}\"' + done + done + ) + . "$tmpfile" + rm "$tmpfile" +} + +function read_config_file { + local return_value=0 + + # Clear variables and arrays + for var in ${update_conf_variables}; do + unset $var + done + + # Source in the configuration file + safe_source "${upd_mod_conf}" ${update_conf_variables} + + # Set module naming/location arrays + local index array_size=0 s + for s in ${#REMOVE_MODULE_NAME[@]} \ + ${#REMOVE_MODULE_LOCATION[@]}; do + ((s > array_size)) && array_size=$s + done + for ((index=0; index < array_size; index++)); do + # Set values + remove_module_name[$index]=${REMOVE_MODULE_NAME[$index]} + remove_module_location[$index]=${REMOVE_MODULE_LOCATION[$index]} + + # FAIL if no remove_module_name + if [[ ! ${remove_module_name[$index]} ]]; then + echo "$(basename ${upd_mod_conf}): Error! No 'REMOVE_MODULE_NAME' directive specified for record #$index." + return_value=1 + fi + if [[ ! ${REMOVE_MODULE_LOCATION[$index]} ]]; then + echo "$(basename ${upd_mod_conf}): Error! No 'REMOVE_MODULE_LOCATION' directive specified for record #$index." + return_value=1 + fi + done + + # Fail if absolutely no REMOVE_MODULE_NAME + if ((${#remove_module_name[@]} == 0)); then + echo "upd_mod_conf: Error! No 'REMOVE_MODULE_NAME' directive specified." + return_value=1 + fi + + # Fail if absolutely no REMOVE_MODULE_LOCATION + if ((${#remove_module_location[@]} == 0)); then + echo "upd_mod_conf: Error! No 'REMOVE_MODULE_LOCATION' directive specified." + return_value=1 + fi + + return $return_value +} + +function read_config_file_or_die { + read_config_file "$@" && return + + err_exit "Bad conf file (${1})." ${err_read_config} +} + +function remove_modules { + local kernel_tree="${install_tree}/${kernelver}" + local dkms_original="${dkms_base_dir}/original_module" + + [[ -e ${kernel_tree} ]] || err_exit "Kernel tree ${kernel_tree} doesn't exist." ${err_kernel_tree} + + for ((count=0; count < ${#remove_module_name[@]}; count++)); do + local kernel_mod=${kernel_tree}${remove_module_location[$count]}/${remove_module_name[$count]}${module_suffix} + local dkms_orig=${dkms_original}/${remove_module_name[$count]}${module_suffix} + + echo "" + echo "${remove_module_name[$count]}${module_suffix}:" + if [ -e ${dkms_orig} ]; then + echo " - An original module was already stored during a previous install" + else + if [ -f "${kernel_mod}" ]; then + echo " - Found ${kernel_mod}" + echo " - Storing in ${dkms_original}/" + echo " - Archiving for uninstallation purposes" + mkdir -p "${dkms_original}/" + mv -f "${kernel_mod}" "${dkms_orig}" + modules_removed="true" + fi + fi + done + + echo "" +} + +function restore_modules { + local kernel_tree="${install_tree}/${kernelver}" + local dkms_original="${dkms_base_dir}/original_module" + local moved="" + + [[ -e ${kernel_tree} ]] || err_exit "Kernel tree ${kernel_tree} doesn't exist." ${err_kernel_tree} + + for ((count=0; count < ${#remove_module_name[@]}; count++)); do + local kernel_mod=${kernel_tree}${remove_module_location[$count]}/${remove_module_name[$count]}${module_suffix} + local dkms_orig=${dkms_original}/${remove_module_name[$count]}${module_suffix} + + echo "" + echo "${remove_module_name[$count]}${module_suffix}:" + if [ -e ${dkms_orig} ]; then + local kernel_mod_dir=$(dirname ${kernel_mod}) + echo " - Archived original module found in the DKMS tree" + echo " - Moving it to: ${kernel_mod_dir}/" + mkdir -p "${kernel_mod_dir}/" + mv -f "${dkms_orig}" "${kernel_mod_dir}/" 2> /dev/null + moved="true" + else + echo " - No original module was found for this module on this kernel." + echo " - Use the dkms install command to reinstall any previous module version." + fi + done + + if [ ${moved} ]; then + [[ $(find ${dkms_original}/* -maxdepth 0 -type f 2>/dev/null) ]] || rm -rf "${dkms_original}" + fi + + echo "" +} + +# main + +if [ $# -lt 4 ] ; then + usage +fi + +arg_check_help "${1}" + +dkms_base_dir="${1}" +shift + +arg_check_help "${1}" + +kernelver="${1}" +shift + +arg_check_help "${1}" + +arch="${1}" +shift + +arg_check_help "${1}" + +action="${1}" +shift + +arg_check_help "${1}" + +# First check, if the DKMS base directory, does already exist +if [ ! -d ${dkms_base_dir} ] ; then + err_exit "DKMS base directory ${dkms_base_dir} doesn't exist!" ${err_dir_not_found} +fi + +script_dir=$(dirname ${BASH_SOURCE[0]}) +upd_mod_conf=${script_dir}/${upd_mod_conf_name} + +# Check for the configuration file +if [ -f ${upd_mod_conf} ] ; then + echo "Using configuration file ${upd_mod_conf}" + + read_config_file_or_die ${upd_mod_conf} + + case "${action}" in + install) remove_modules + if [ ${modules_removed} ]; then + echo "!!!! NOTE NOTE NOTE !!!!" + echo " There is NO uninstall hook in DKMS available." + echo " This script has saved some modules to" + echo " ${dkms_base_dir}/original_module" + echo " Prior to uninstalling this DKMS module execute" + echo " $0 ${dkms_base_dir} ${kernelver} ${arch} uninstall" + echo "" + fi + ;; + uninstall) restore_modules ;; + *) err_exit "Invalid action '${action}' given!" ${err_action} + esac + + + exit_print "Done!" ${err_ok} +else + exit_print "Nothing to do!" ${err_ok} +fi + diff --git a/install.sh b/install.sh index 33215c7..1a5478b 100755 --- a/install.sh +++ b/install.sh @@ -1,7 +1,7 @@ #!/bin/bash # Enable some staging drivers -#make stagingconfig +make stagingconfig echo "V4L drivers building..." make -j5