cryptdisks-functions 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. #
  2. # This file is for inclusion with
  3. # . /lib/cryptsetup/cryptdisks-functions
  4. # and should not be executed directly.
  5. PATH="/usr/sbin:/usr/bin:/sbin:/bin"
  6. CRYPTDISKS_ENABLE="Yes"
  7. #set -x
  8. # Sanity check #1
  9. [ -x /sbin/cryptsetup ] || exit 0
  10. . /lib/lsb/init-functions
  11. . /lib/cryptsetup/functions
  12. if [ -r /etc/default/cryptdisks ]; then
  13. . /etc/default/cryptdisks
  14. fi
  15. MOUNT="$CRYPTDISKS_MOUNT"
  16. # do_start()
  17. # Unlock all devices in the crypttab(5)
  18. do_start() {
  19. [ -s "$TABFILE" ] || return 0
  20. # Create locking directory before invoking cryptsetup(8) to avoid warnings
  21. mkdir -pm0700 /run/cryptsetup
  22. modprobe -qb dm-mod || true
  23. modprobe -qb dm-crypt || true
  24. dmsetup mknodes >/dev/null 2>&1 || true
  25. if [ "$INITSTATE" != "init" ]; then
  26. log_action_begin_msg "Starting $INITSTATE crypto disks"
  27. fi
  28. mount_fs
  29. crypttab_foreach_entry _do_start_callback
  30. umount_fs
  31. log_action_end_msg 0
  32. }
  33. _do_start_callback() {
  34. setup_mapping || log_action_end_msg $?
  35. }
  36. # mount_fs()
  37. # Premounts file systems
  38. mount_fs() {
  39. local point
  40. MOUNTED=""
  41. for point in $MOUNT; do
  42. if mount "$point" >/dev/null; then
  43. MOUNTED="$MOUNTED $point"
  44. fi
  45. done
  46. }
  47. # Postunmounts file systems
  48. umount_fs() {
  49. local point
  50. for point in $MOUNTED; do
  51. umount "$point" >/dev/null
  52. done
  53. }
  54. # setup_mapping()
  55. # Set up a crypttab(5) mapping defined by $CRYPTTAB_NAME,
  56. # $CRYPTTAB_SOURCE, $CRYPTTAB_KEY, $CRYPTTAB_OPTIONS.
  57. setup_mapping() {
  58. if dm_blkdevname "$CRYPTTAB_NAME" >/dev/null; then
  59. device_msg "running"
  60. return 0
  61. fi
  62. local loud="${DEFAULT_LOUD:-}"
  63. crypttab_parse_options --export --missing-path=fail || return 1
  64. if [ -n "${CRYPTTAB_OPTION_quiet+x}" ]; then
  65. loud="no"
  66. elif [ -n "${CRYPTTAB_OPTION_loud+x}" ]; then
  67. loud="yes"
  68. fi
  69. if [ -n "${CRYPTTAB_OPTION_noearly+x}" ] && [ "$INITSTATE" = "early" ]; then
  70. [ -z "${FORCE_START-}" ] || device_msg "ignored"
  71. return 0
  72. fi
  73. if [ -n "${CRYPTTAB_OPTION_noauto+x}" ] && [ "$INITSTATE" != "manual" ]; then
  74. [ -z "${FORCE_START-}" ] || device_msg "ignored"
  75. return 0
  76. fi
  77. if [ -z "${CRYPTTAB_OPTION_keyscript+x}" ] && [ "$CRYPTTAB_KEY" != "none" ]; then
  78. if ! crypttab_key_check; then
  79. device_msg "invalid key"
  80. return 1
  81. fi
  82. CRYPTTAB_OPTION_tries=1
  83. fi
  84. if ! crypttab_resolve_source; then
  85. if [ "$loud" = "yes" ]; then
  86. device_msg "skipped, device $CRYPTTAB_SOURCE does not exist"
  87. fi
  88. return 1
  89. fi
  90. device_msg "starting"
  91. local out tmpdev
  92. get_crypt_type # set CRYPTTAB_TYPE to the type of crypt device
  93. if [ "$CRYPTTAB_TYPE" != "luks" ]; then
  94. if ! out="$(/lib/cryptsetup/checks/un_blkid "$CRYPTTAB_SOURCE" 2>/dev/null)" &&
  95. ! /lib/cryptsetup/checks/blkid "$CRYPTTAB_SOURCE" swap >/dev/null; then
  96. # fail if the device has a filesystem; unless it's swap,
  97. # otherwise people can't easily convert an existing
  98. # plainttext swap partition to an encrypted one
  99. log_warning_msg "$CRYPTTAB_NAME: the precheck for '$CRYPTTAB_SOURCE' failed: $out"
  100. return 1
  101. fi
  102. fi
  103. local count=0 maxtries="${CRYPTTAB_OPTION_tries:-3}" fstype rv
  104. local target="$CRYPTTAB_NAME"
  105. CRYPTTAB_NAME="${CRYPTTAB_NAME}_unformatted" # XXX potential conflict
  106. while [ $maxtries -le 0 ] || [ $count -lt $maxtries ]; do
  107. if [ -z "${CRYPTTAB_OPTION_keyscript+x}" ] && [ "$CRYPTTAB_KEY" != "none" ]; then
  108. # unlock via keyfile
  109. unlock_mapping "$CRYPTTAB_KEY"
  110. else
  111. # unlock interactively or via keyscript
  112. CRYPTTAB_NAME="$target" run_keyscript "$CRYPTTAB_KEY" "$count" | unlock_mapping
  113. fi
  114. rv=$?
  115. count=$(( $count + 1 ))
  116. if [ $rv -ne 0 ] || ! tmpdev="$(dm_blkdevname "$CRYPTTAB_NAME")"; then
  117. continue
  118. fi
  119. if [ -n "${CRYPTTAB_OPTION_check+x}" ] && \
  120. ! "$CRYPTTAB_OPTION_check" "$tmpdev" $CRYPTTAB_OPTION_checkargs ; then
  121. log_warning_msg "$target: the check for '$CRYPTTAB_NAME' failed"
  122. cryptsetup remove -- "$CRYPTTAB_NAME"
  123. continue
  124. fi
  125. if [ "${CRYPTTAB_OPTION_swap+x}" ]; then
  126. if out="$(/lib/cryptsetup/checks/un_blkid "$tmpdev" 2>/dev/null)" ||
  127. /lib/cryptsetup/checks/blkid "$tmpdev" swap >/dev/null 2>&1; then
  128. mkswap "$tmpdev" >/dev/null 2>&1
  129. else
  130. log_warning_msg "$target: the check for '$CRYPTTAB_NAME' failed. $CRYPTTAB_NAME contains data: $out"
  131. cryptsetup remove -- "$CRYPTTAB_NAME"
  132. return 1
  133. fi
  134. elif [ "${CRYPTTAB_OPTION_tmp+x}" ]; then
  135. local tmpdir="$(mktemp --tmpdir="/run/cryptsetup" --directory)" rv=0
  136. if ! mkfs -t "$CRYPTTAB_OPTION_tmp" -q "$tmpdev" >/dev/null 2>&1 ||
  137. ! mount -t "$CRYPTTAB_OPTION_tmp" "$tmpdev" "$tmpdir" ||
  138. ! chmod 1777 "$tmpdir"; then
  139. rv=1
  140. fi
  141. umount "$tmpdir" || true
  142. rmdir "$tmpdir" || true
  143. [ $rv -eq 0 ] || return $rv
  144. fi
  145. if command -v udevadm >/dev/null 2>&1; then
  146. udevadm settle
  147. fi
  148. dmsetup rename -- "$CRYPTTAB_NAME" "$target"
  149. device_msg "$target" "started"
  150. return 0
  151. done
  152. device_msg "$target" "failed"
  153. return 1
  154. }
  155. # Removes all mappings in crypttab
  156. do_stop() {
  157. dmsetup mknodes
  158. log_action_begin_msg "Stopping $INITSTATE crypto disks"
  159. crypttab_foreach_entry _do_stop_callback
  160. log_action_end_msg 0
  161. }
  162. _do_stop_callback() {
  163. local i rv=0
  164. for i in 1 2 4 8 16 32; do
  165. remove_mapping "$CRYPTTAB_NAME" 3<&- && break || rv=$?
  166. if [ $rv -eq 1 ] || [ $rv -eq 2 -a $i -gt 16 ]; then
  167. log_action_end_msg $rv
  168. break
  169. fi
  170. log_action_cont_msg "$CRYPTTAB_NAME busy..."
  171. sleep $i
  172. done
  173. }
  174. # device_msg([$name], $message)
  175. # Convenience function to handle $VERBOSE
  176. device_msg() {
  177. local name message
  178. if [ $# -eq 1 ]; then
  179. name="$CRYPTTAB_NAME"
  180. message="$1"
  181. else
  182. name="$1"
  183. message="$2"
  184. fi
  185. if [ "$VERBOSE" != "no" ]; then
  186. log_action_cont_msg "$name ($message)"
  187. fi
  188. }
  189. # remove_mapping($target)
  190. # Remove mapping $target
  191. remove_mapping() {
  192. local CRYPTTAB_NAME="$1"
  193. if ! dm_blkdevname "$CRYPTTAB_NAME" >/dev/null; then
  194. device_msg "stopped"
  195. return 0
  196. fi
  197. if [ "$(dmsetup info --noheadings -c -o subsystem -- "$CRYPTTAB_NAME")" != "CRYPT" ]; then
  198. device_msg "error"
  199. return 1
  200. fi
  201. local opencount="$(dmsetup info -c --noheadings -o open -- "$CRYPTTAB_NAME" 2>/dev/null || true)"
  202. if [ -z "$opencount" ]; then
  203. device_msg "error"
  204. return 1
  205. elif [ "$opencount" != "0" ]; then
  206. device_msg "busy"
  207. if [ "$INITSTATE" = "early" ] || [ "$INITSTATE" = "manual" ]; then
  208. return 1
  209. elif [ "$INITSTATE" = "remaining" ]; then
  210. return 2
  211. fi
  212. return 0
  213. fi
  214. if cryptsetup remove -- "$CRYPTTAB_NAME"; then
  215. device_msg "stopping"
  216. return 0
  217. else
  218. device_msg "error"
  219. return 1
  220. fi
  221. }
  222. # vim: set filetype=sh :