scripts/forensic-mark-readonly: fix parent device handling + their usage via READONLY...
[grml-udev-config.git] / scripts / forensic-mark-readonly
1 #!/bin/sh
2 # Filename:      forensic-mark-readonly
3 # Purpose:       force block devices to read-only mode when booting with boot option read-only
4 # Authors:       grml-team (grml.org), (c) Michael Prokop <mika@grml.org>
5 # Bug-Reports:   see http://grml.org/bugs/
6 # License:       This file is licensed under the GPL v2 or any later version.
7 ################################################################################
8
9 # check for read-only bootoption
10 if ! grep -q read-only /proc/cmdline ; then
11   exit 0
12 fi
13
14 # see linux source -> Documentation/admin-guide/sysfs-rules.rst
15 get_blockdev_dir() {
16   for dir in /sys/subsystem/block /sys/class/block /sys/block ; do
17     [ -d "${dir}" ] && echo "${dir}" && return
18   done
19 }
20
21 base() {
22   echo "${1##*/}"
23 }
24
25 dir() {
26   echo "${1%/*}"
27 }
28
29 is_ro() {
30   [ "$(blockdev --getro "$1")" = "1" ] && return 0 || return 1
31 }
32
33 if [ -z "${1:-}" ] ; then
34   echo "Error: usage: <$0> <blockdevice>" >&2
35   exit 1
36 fi
37
38 # accept /dev/foo from command line but also just "foo" from udev
39 case "$1" in
40   /dev/*)
41     BLOCK_DEVICE="$1"
42     ;;
43   *)
44     BLOCK_DEVICE="/dev/$1"
45     ;;
46 esac
47
48 SYS_DIR="$(get_blockdev_dir)"
49
50 base_device=$(base "${BLOCK_DEVICE}")
51 if [ -n "${SYS_DIR}" ] && [ -n "${base_device}" ] ; then
52   tmp_parent="$(readlink -f "${SYS_DIR}"/*/"${base_device}")"
53   if [ -d "${tmp_parent}" ] ; then
54     parent_device=$(dir "${tmp_parent}")
55     parent_device=$(base "${parent_device}")
56     parent_device="/dev/${parent_device}"
57   fi
58   unset tmp_parent
59 fi
60
61 # support configuration file
62 if [ -r /etc/grml/forensic.conf ] ; then
63   READONLY_MODE=""
64   READONLY_IGNORE=""
65
66   . /etc/grml/forensic.conf
67
68   if [ "${READONLY_MODE:-}" = "disable" ] ; then
69     logger -t forensic-mark-readonly "not setting '${BLOCK_DEVICE}' to read-only as disabled via config"
70     exit 0
71   fi
72
73   if [ -n "${READONLY_IGNORE:-}" ] ; then
74     if printf "%s\n" "${READONLY_IGNORE:-}" | grep -qw "${parent_device}" ; then
75       if [ -n "${parent_device:-}" ] ; then
76         logger -t forensic-mark-readonly "not setting '${BLOCK_DEVICE}' (parent device: '${parent_device}') to read-only as present in ignore list"
77       else
78         logger -t forensic-mark-readonly "not setting '${BLOCK_DEVICE}' to read-only as present in ignore list"
79       fi
80       exit 0
81     fi
82   fi
83 fi
84
85 if is_ro "${BLOCK_DEVICE}" ; then
86   logger -t forensic-mark-readonly "device ${BLOCK_DEVICE} already set to read-only mode, nothing to do"
87 elif [ -n "${parent_device}" ] && ! is_ro "${parent_device}" ; then
88   logger -t forensic-mark-readonly "parent device ${parent_device} is set read-write, not modifying"
89   logger -t forensic-mark-readonly "use blockdev --setro ${BLOCK_DEVICE} to set it manually"
90 else
91   logger -t forensic-mark-readonly "setting ${BLOCK_DEVICE} [${ID_SERIAL}] to read-only"
92
93   if blockdev --setro "${BLOCK_DEVICE}" ; then
94     logger -t forensic-mark-readonly "|-> done; execute 'blockdev --setrw ${BLOCK_DEVICE}' to unlock"
95   else
96     logger -t forensic-mark-readonly "|-> error while executing blockdev: $(blockdev --setro "${BLOCK_DEVICE}" 2>&1)"
97   fi
98 fi
99
100 ## END OF FILE #################################################################