]> git.ipfire.org Git - thirdparty/dracut-ng.git/commitdiff
feat(90dm): close crypt devices using cryptsetup
authorKamil Szczęk <kamil@szczek.dev>
Sun, 19 May 2024 16:12:52 +0000 (18:12 +0200)
committerNeal Gompa (ニール・ゴンパ) <ngompa13@gmail.com>
Sat, 25 May 2024 21:24:45 +0000 (17:24 -0400)
This commit changes the behavior of the shutdown script in the 90dm
module to use more specialized tools for removing dm-crypt mappers.
When dealing with a dm-crypt mapper, the shutdown script will try to use
systemd-cryptsetup, cryptsetup or dmsetup, whichever is available in the
specified order. This lets systemd-cryptsetup or cryptsetup perform any
necessary cleanup steps when detaching volumes activated by those tools.

Resolves #204

modules.d/90dm/dm-shutdown.sh

index bd7134a9ad2e0b6ea715a40fc8f6da32c55d9842..93b62bbc86899326c1cc9e435351ca1646db8872 100755 (executable)
@@ -2,26 +2,40 @@
 
 _remove_dm() {
     local dev="$1"
+    local final="$2"
     local s
     local devname
 
     for s in /sys/block/"${dev}"/holders/dm-*; do
         [ -e "${s}" ] || continue
-        _remove_dm "${s##*/}"
+        _remove_dm "${s##*/}" "$final" || return $?
     done
-    # multipath devices might have MD devices on top,
-    # which are removed after this script. So do not
-    # remove those to avoid spurious errors
+
+    read -r devname < /sys/block/"${dev}"/dm/name
     case $(cat /sys/block/"${dev}"/dm/uuid) in
         mpath-*)
+            # multipath devices might have MD devices on top,
+            # which are removed after this script. So do not
+            # remove those to avoid spurious errors
             return 0
             ;;
-        *)
-            read -r devname < /sys/block/"${dev}"/dm/name
-            dmsetup -v --noudevsync remove "$devname" || return $?
+        CRYPT-*)
+            if command -v systemd-cryptsetup > /dev/null; then
+                DM_DISABLE_UDEV=true SYSTEMD_LOG_LEVEL=debug systemd-cryptsetup detach "$devname" && return 0
+            elif command -v cryptsetup > /dev/null; then
+                DM_DISABLE_UDEV=true cryptsetup close --debug "$devname" && return 0
+            else
+                dmsetup -v --noudevsync remove "$devname"
+                return $?
+            fi
+
+            # try using plain dmsetup if we're on the final attempt.
+            [ -z "$final" ] && return 1
             ;;
     esac
-    return 0
+
+    dmsetup -v --noudevsync remove "$devname"
+    return $?
 }
 
 _do_dm_shutdown() {
@@ -33,9 +47,9 @@ _do_dm_shutdown() {
     for dev in /sys/block/dm-*; do
         [ -e "${dev}" ] || continue
         if [ "x$final" != "x" ]; then
-            _remove_dm "${dev##*/}" || ret=$?
+            _remove_dm "${dev##*/}" "$final" || ret=$?
         else
-            _remove_dm "${dev##*/}" > /dev/null 2>&1 || ret=$?
+            _remove_dm "${dev##*/}" "$final" > /dev/null 2>&1 || ret=$?
         fi
     done
     if [ "x$final" != "x" ]; then