Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add broken status #357

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions dkms.8.in
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,14 @@ Returns the current status of modules, versions and kernels within
the tree as well as whether they have been added, built or installed.
Status can be shown for just a certain module, a certain kernel,
a module/version combination or a module/version/kernel combination.

If the source directory, or the symbolic link 'source' pointing to it is missing,
the status of the module/version combination will be displayed as 'broken'.
In that case dkms will not perform any other action on that particular module/version combination.
Manual intervention is required.
If only the symbolic link 'source' is missing, the
.B add
action may be used to re-add the module/version combination to dkms.
.SY autoinstall
.YS
.IP "" 4
Expand Down
46 changes: 44 additions & 2 deletions dkms.in
Original file line number Diff line number Diff line change
Expand Up @@ -1404,10 +1404,24 @@ list_each_installed_module()
done
}

# Check if either the module source, or the symlink pointing to it is missing
# A module can only be in this broken state, if the user or a faulty program
# messed up. The module then is considered volatile, because there is no reliable
# way to tell if files in the source tree are still in a valid state.
# Therefor any action (except 'add', if only the symlink is missing)
# to operate on the module has to be refused.
# Manual intervention by the user is required to return to a sane state.
is_module_broken() {
[[ $1 && $2 ]] || return 1
[[ -d $dkms_tree/$1/$2 ]] || return 2
[[ -L $dkms_tree/$1/$2/source && ! -d $dkms_tree/$1/$2/source ]] && return
[[ ! -L $dkms_tree/$1/$2/source && -d $source_tree/$1-$2/ ]] && return
}

is_module_added() {
[[ $1 && $2 ]] || return 1
[[ -d $dkms_tree/$1/$2 ]] || return 2
[[ -L $dkms_tree/$1/$2/source || -d $dkms_tree/$1/$2/source ]];
[[ -L $dkms_tree/$1/$2/source && -d $dkms_tree/$1/$2/source ]] || return 2
}

is_module_built() {
Expand Down Expand Up @@ -1607,6 +1621,12 @@ do_uninstall()
[[ $(find $dkms_tree/$module/original_module/* -maxdepth 0 -type d 2>/dev/null) ]] || rm -rf "$dkms_tree/$module/original_module"
}

module_is_broken_and_die() {
is_module_broken "$module" "$module_version" && die 4 $"$module/$module_version is broken!"\
$"Missing the source directory or the symbolic link pointing to it."\
$"Manual intervention is required!"
}

module_is_added_or_die()
{
is_module_added "$module" "$module_version" || die 3 \
Expand Down Expand Up @@ -1763,7 +1783,7 @@ do_status_weak()
# interested in, but that the DKMS internals do not usually care about.
module_status_built_extra() (
set_module_suffix "$3"
read_conf_or_die "$3" "$4" "$dkms_tree/$1/$2/source/dkms.conf" 2>/dev/null
read_conf "$3" "$4" "$dkms_tree/$1/$2/source/dkms.conf" 2>/dev/null
[[ -d $dkms_tree/$1/original_module/$3/$4 ]] && echo -n " (original_module exists)"
for ((count=0; count < ${#dest_module_name[@]}; count++)); do
tree_mod=$(compressed_or_uncompressed "$dkms_tree/$1/$2/$3/$4/module" "${dest_module_name[$count]}")
Expand Down Expand Up @@ -1808,6 +1828,7 @@ module_status() {
mv="${directory#$dkms_tree/}"
m="${mv%/*}"
v="${mv#*/}"
is_module_broken "$m" "$v" && { echo "broken $m/$v"; continue; }
is_module_added "$m" "$v" || continue
ret=0
module_status_built "$m" "$v" "$3" "$4" || echo "added $m/$v"
Expand All @@ -1828,6 +1849,11 @@ do_status() {
while read status mvka; do
IFS=/ read m v k a <<< "$mvka"
case $status in
broken)
echo "$m/$v: $status"
error $"$m/$v: Missing the module source directory or the symbolic link pointing to it."\
$"Manual intervention is required!"
;;
added)
echo "$m/$v: $status"
;;
Expand Down Expand Up @@ -2104,6 +2130,13 @@ run_match()
echo $"Module: $template_module"
echo $"Version: $template_version"

# Continue if the status is broken, as there is nothing we can do
if is_module_broken "$template_module" "$template_version"; then
error $"$template_module/$template_version is broken!"\
$"Missing the source directory or the symbolic link pointing to it."\
$"Manual intervention is required!"
continue
fi
maybe_build_module "$template_module" "$template_version" "$kernelver" "$arch"
maybe_install_module "$template_module" "$template_version" "$kernelver" "$arch"
done < <(echo "$template_kernel_status")
Expand Down Expand Up @@ -2232,6 +2265,12 @@ autoinstall() {
# a list of modules and their latest version.
while read status mvka; do
IFS='/' read m v k a <<< "$mvka"
# If the module status is broken there is nothing that can be done
if [[ $status = broken ]]; then
error $"$m/$v is broken! Missing the source directory or the symbolic link pointing to it."\
$"Manual intervention is required!"
continue
fi
if [[ -z "${latest["$m"]}" ]]; then
known_modules[${#known_modules[@]}]="$m"
latest["$m"]="$v"
Expand Down Expand Up @@ -2586,12 +2625,14 @@ setup_kernels_arches "$action"
case "$action" in
remove | unbuild | uninstall)
check_module_args $action
module_is_broken_and_die
module_is_added_or_die
[[ $action = uninstall ]] && check_root || check_rw_dkms_tree
${action}_module
;;
add | build | install)
check_all_is_banned $action # TODO: fix/enable --all
[[ $action != add ]] && module_is_broken_and_die
[[ $action = install ]] && check_root || check_rw_dkms_tree
${action}_module
;;
Expand All @@ -2603,6 +2644,7 @@ match)
;;
mktarball)
check_module_args mktarball
module_is_broken_and_die
module_is_added_or_die
make_tarball
;;
Expand Down
190 changes: 190 additions & 0 deletions run_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -1747,4 +1747,194 @@ trap - EXIT
echo 'Checking that the environment is clean again'
check_no_dkms_test

############################################################################
### Testing 'broken' status ###
############################################################################

echo
echo 'Running BROKEN tests'
echo

echo 'Adding the test module by directory'
run_with_expected_output dkms add test/dkms_test-1.0 << EOF
Creating symlink /var/lib/dkms/dkms_test/1.0/source -> /usr/src/dkms_test-1.0
EOF

echo ' Removing symlink /var/lib/dkms/dkms_test/1.0/source'
rm /var/lib/dkms/dkms_test/1.0/source

echo 'Checking broken status'
run_with_expected_output dkms status dkms_test/1.0 << EOF
dkms_test/1.0: broken
Error! dkms_test/1.0: Missing the module source directory or the symbolic link pointing to it.
Manual intervention is required!
EOF

echo 'Re-adding the test module'
run_with_expected_output dkms add dkms_test/1.0 << EOF
Creating symlink /var/lib/dkms/dkms_test/1.0/source -> /usr/src/dkms_test-1.0
EOF

echo ' Removing symlink /var/lib/dkms/dkms_test/1.0/source'
rm /var/lib/dkms/dkms_test/1.0/source

echo 'Building broken test module (expected erorr)'
run_with_expected_error 4 dkms build dkms_test/1.0 << EOF
Error! dkms_test/1.0 is broken!
Missing the source directory or the symbolic link pointing to it.
Manual intervention is required!
EOF

echo 'Installing broken test module (expected erorr)'
run_with_expected_error 4 dkms install dkms_test/1.0 << EOF
Error! dkms_test/1.0 is broken!
Missing the source directory or the symbolic link pointing to it.
Manual intervention is required!
EOF

echo 'Unbuild broken test module (expected erorr)'
run_with_expected_error 4 dkms unbuild dkms_test/1.0 << EOF
Error! dkms_test/1.0 is broken!
Missing the source directory or the symbolic link pointing to it.
Manual intervention is required!
EOF

echo 'Uninstall broken test module (expected erorr)'
run_with_expected_error 4 dkms uninstall dkms_test/1.0 << EOF
Error! dkms_test/1.0 is broken!
Missing the source directory or the symbolic link pointing to it.
Manual intervention is required!
EOF

echo 'Adding the multiver test module 1.0 by directory'
run_with_expected_output dkms add test/dkms_multiver_test/1.0 << EOF
Creating symlink /var/lib/dkms/dkms_multiver_test/1.0/source -> /usr/src/dkms_multiver_test-1.0
EOF

echo 'Checking broken status'
run_with_expected_output dkms status << EOF
dkms_multiver_test/1.0: added
dkms_test/1.0: broken
Error! dkms_test/1.0: Missing the module source directory or the symbolic link pointing to it.
Manual intervention is required!
EOF

echo 'Remove broken test module (expected erorr)'
run_with_expected_error 4 dkms remove dkms_test/1.0 << EOF
Error! dkms_test/1.0 is broken!
Missing the source directory or the symbolic link pointing to it.
Manual intervention is required!
EOF

echo 'Re-adding the test module'
run_with_expected_output dkms add dkms_test/1.0 << EOF
Creating symlink /var/lib/dkms/dkms_test/1.0/source -> /usr/src/dkms_test-1.0
EOF

echo ' Removing source tree /usr/src/dkms_test-1.0/'
rm -rf /usr/src/dkms_test-1.0/

echo 'Checking broken status'
run_with_expected_output dkms status << EOF
dkms_multiver_test/1.0: added
dkms_test/1.0: broken
Error! dkms_test/1.0: Missing the module source directory or the symbolic link pointing to it.
Manual intervention is required!
EOF

echo 'Removing dkms_multiver_test'
dkms remove dkms_multiver_test/1.0 -k "${KERNEL_VER}" > /dev/null

echo 'Removing dkms_test'
rm -rf /var/lib/dkms/dkms_test/

echo 'Adding and building the test module by directory'
set_signing_message "dkms_test" "1.0"
run_with_expected_output dkms build test/dkms_test-1.0 -k "${KERNEL_VER}" << EOF
Creating symlink /var/lib/dkms/dkms_test/1.0/source -> /usr/src/dkms_test-1.0

Building module:
Cleaning build area...
Building module(s)...
${SIGNING_MESSAGE}Cleaning build area...
EOF

echo 'Adding and building the multiver test module 1.0 by directory'
set_signing_message "dkms_multiver_test" "1.0"
run_with_expected_output dkms build test/dkms_multiver_test/1.0 -k "${KERNEL_VER}" << EOF
Creating symlink /var/lib/dkms/dkms_multiver_test/1.0/source -> /usr/src/dkms_multiver_test-1.0

Building module:
Cleaning build area...
Building module(s)...
${SIGNING_MESSAGE}Cleaning build area...
EOF

echo ' Removing symlink /var/lib/dkms/dkms_multiver_test/1.0/source'
rm /var/lib/dkms/dkms_multiver_test/1.0/source

echo 'Adding and building the multiver test module 2.0 by directory'
set_signing_message "dkms_multiver_test" "2.0"
run_with_expected_output dkms build test/dkms_multiver_test/2.0 -k "${KERNEL_VER}" << EOF
Creating symlink /var/lib/dkms/dkms_multiver_test/2.0/source -> /usr/src/dkms_multiver_test-2.0

Building module:
Cleaning build area...
Building module(s)...
${SIGNING_MESSAGE}Cleaning build area...
EOF

echo 'Running dkms autoinstall'
run_with_expected_output dkms autoinstall -k "${KERNEL_VER}" << EOF
Error! dkms_multiver_test/1.0 is broken! Missing the source directory or the symbolic link pointing to it.
Manual intervention is required!

dkms_test.ko${mod_compression_ext}:
Running module version sanity check.
- Original module
- No original module exists within this kernel
- Installation
- Installing to /lib/modules/${KERNEL_VER}/${expected_dest_loc}/
depmod...
dkms autoinstall on ${KERNEL_VER}/${KERNEL_ARCH} succeeded for dkms_test
EOF
run_with_expected_output dkms status << EOF
dkms_multiver_test/1.0: broken
Error! dkms_multiver_test/1.0: Missing the module source directory or the symbolic link pointing to it.
Manual intervention is required!
dkms_multiver_test/2.0, ${KERNEL_VER}, ${KERNEL_ARCH}: built
dkms_test/1.0, ${KERNEL_VER}, ${KERNEL_ARCH}: installed
EOF

echo 'Removing all modules'
echo ' Removing the test module'
run_with_expected_output dkms remove dkms_test/1.0 -k "${KERNEL_VER}" << EOF
Module dkms_test-1.0 for kernel ${KERNEL_VER} (${KERNEL_ARCH}).
Before uninstall, this module version was ACTIVE on this kernel.

dkms_test.ko${mod_compression_ext}:
- Uninstallation
- Deleting from: /lib/modules/${KERNEL_VER}/${expected_dest_loc}/
- Original module
- No original module was found for this module on this kernel.
- Use the dkms install command to reinstall any previous module version.
Deleting module dkms_test-1.0 completely from the DKMS tree.
EOF

echo ' Removing the multi_ver_test 2.0 module'
run_with_expected_output dkms remove -m dkms_multiver_test -v 2.0 -k "${KERNEL_VER}" << EOF
Module dkms_multiver_test 2.0 is not installed for kernel ${KERNEL_VER} (${KERNEL_ARCH}). Skipping...
Deleting module dkms_multiver_test-2.0 completely from the DKMS tree.
EOF

echo ' Removing directories: /var/lib/dkms/dkms_test/ /var/lib/dkms/dkms_multiver_test /usr/src/dkms_test-1.0 /usr/src/dkms_multiver_test-?.0'
rm -rf /var/lib/dkms/dkms_test/ /var/lib/dkms/dkms_multiver_test /usr/src/dkms_test-1.0 /usr/src/dkms_multiver_test-?.0

echo 'Checking that the environment is clean again'
check_no_dkms_test

echo
echo 'End of BROKEN tests'
echo

echo 'All tests successful :)'