Automated fsck for encrypted home directories

As you all know the unexpected does happen and sometimes you end up with a filesystem in an inconsistent state.
The nice thing is that on bootup the OS automatically repairs most of these errors, except for the encrypted home directories.

The problem is that doing an fsck on an encrypted home directory can be quite a daunting task if you don’t know how the whole thing works.

To address this shortcoming I wrote a script to automate the whole process.
Here’s how to use it

Open a terminal in your GUI and change to root.

Create the file fsck.crypthomedir.sh in /root/bin/ with the following code


#!/bin/bash
#
# This script was written with the intent of simplifying the running of fsck
# on an encrypted home directory using ext2 in openSUSE.
#

# Check if we received the correct parameters
user=''

if [ $# -eq 0 ]; then
    echo "Usage: $0 user"
    echo "Example: $0 myusername"
    echo ""
    exit 2
else
    user=$1
fi

# Find and read the variables for the encrypted home directory
volume=$(grep -E "<volume fstype=\"crypt\".*user=\"${user}\".*" /etc/security/pam_mount.conf.xml)

path=''
fskeypath=''
fskeycipher=''
cipher=''
options=''
mountpoint=''

if [ ${#volume} -lt 1 ]; then
    echo "Could not find crypt volume for user ${user}"
    exit 1
else
    volumeparameters=($(echo ${volume} | sed 's/<volume //;s/\/><\/pam_mount>//'))
    for i in ${!volumeparameters
[li]}; do[/li]        parameter=$(echo "${volumeparameters[$i]}" | sed 's/\(.*\)=.*/\1/')
        parametervalue=$(echo "${volumeparameters[$i]}" | sed 's/.*="\(.*\)"/\1/')

        case ${parameter} in
          path)    
            path=${parametervalue};;
          fskeypath)    
            fskeypath=${parametervalue};;
          fskeycipher)    
            fskeycipher=${parametervalue};;
          cipher)    
            cipher=${parametervalue};;
          options)    
            options=${parametervalue};;
          mountpoint)    
            mountpoint=${parametervalue};;
          *)
            ;;
        esac
    done
fi

# Check if the directory is already mounted
mountcount=$(mount | grep "${mountpoint}" --count)

if [ ${mountcount} -gt 0 ]; then
    echo "crypt volume ${mountpoint} for user ${user} is mounted."
    echo "Please make sure that ${user} is logged out and the volume unmounted before continuing."
    exit 1
fi

# Check if we are root
if [ ${UID} -ne 0 ]; then
    echo "root permissions are required to run fsck on the crypt volume ${mountpoint} for user ${user}"
    exit 1
fi

# Decrypt the homedir
fsckhome=$(mktemp --dry-run 'fsckhomeXXX')
openssl "${fskeycipher}" -d -in "${fskeypath}" | cryptsetup luksOpen "${path}" "${fsckhome}"

# Check if the homedir was decrypted
mappercount=$(ls -1 /dev/mapper/${fsckhome} | wc -l)

if [ ${mappercount} -eq 0 ]; then
        echo "crypt volume ${mountpoint} for user ${user} was not opened or could not be decrypted"
else
    # Run fsck
    #  -D  Optimize  directories  in  filesystem
    #  -f  Force checking even if the file system seems clean
    #  -v  Verbose mode
    #  -p  Automatically  repair  ("preen")  the file system
    e2fsck -D -f -v /dev/mapper/${fsckhome}
    sleep 2
fi

# Close the homedir
cryptsetup luksClose ${fsckhome}

# Check if the homedir was closed
mappercount=$(ls -1 /dev/mapper/${fsckhome} | wc -l)

if [ ${mappercount} -gt 0 ]; then
        echo "crypt volume ${mountpoint} for user ${user} was not closed or could not be encrypted"
fi

echo "Finished checking crypt volume for user ${user}"


then, still as root run the following


chown root:root /root/bin/fsck.crypthomedir.sh
chmod 744 /root/bin/fsck.crypthomedir.sh

To check the filesystem first reboot.
Do this to make it easy on yourself and make sure that the homedirectory is unmounted.

When the login prompt comes up don’t log in, switch to one of the terminals (Ctrl-Alt-F1)
Log in as root and run

fsck.crypthomedir.sh <usernameyouwanttocheckhere>

for example fsck.crypthomedir.sh myusername

It will prompt you for the password and start checking the volume.
fsck might ask a few additional prompts but when it’s done it will close the volume again.

Log out as root, switch to the GUI (Ctrl-Alt-F7) and log in as the user.

DONE rotfl!