bind-dirs.sh 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. #!/bin/bash -e
  2. # vim: set ts=4 sw=4 sts=4 et :
  3. #
  4. # bind-dirs
  5. # Binds directories which allows changes in TemplateBasedVM to persist.
  6. #
  7. # To umount all bind-dirs, just pass any arg in $1, like umount
  8. #
  9. # Copyright (C) 2014 - 2015 Jason Mehring <nrgaway@gmail.com>
  10. # Copyright (C) 2014 - 2015 Patrick Schleizer <adrelanos@riseup.net>
  11. # License: GPL-2+
  12. #
  13. # This program is free software; you can redistribute it and/or
  14. # modify it under the terms of the GNU General Public License
  15. # as published by the Free Software Foundation; either version 2
  16. # of the License, or (at your option) any later version.
  17. #
  18. # This program is distributed in the hope that it will be useful,
  19. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  20. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  21. # GNU General Public License for more details.
  22. #
  23. # You should have received a copy of the GNU General Public License
  24. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  25. # Source Qubes library.
  26. . /usr/lib/qubes/init/functions
  27. prerequisite() {
  28. if ! is_rwonly_persistent ; then
  29. true "No TemplateBasedVM detected. Exiting."
  30. exit 0
  31. fi
  32. }
  33. init() {
  34. [ -n "$rw_dest_dir" ] || rw_dest_dir="/rw/bind-dirs"
  35. [ -n "$symlink_level_max" ] || symlink_level_max="10"
  36. mkdir --parents "$rw_dest_dir"
  37. shopt -s nullglob
  38. shopt -s dotglob
  39. }
  40. legacy() {
  41. ## The legacy function gets overwritten by Whonix:
  42. ## https://github.com/Whonix/qubes-whonix/blob/master/usr/lib/qubes-bind-dirs.d/41_qubes-whonix-legacy.conf
  43. ## Please do not remove this legacy function without coordination with Whonix.
  44. true
  45. }
  46. bind_dirs() {
  47. ## legend
  48. ## fso: file system object
  49. ## ro: read-only
  50. ## rw: read-write
  51. for fso_ro in ${binds[@]}; do
  52. local symlink_level_counter
  53. symlink_level_counter="0"
  54. while true; do
  55. if [ -h "$fso_ro" ]; then
  56. ## Resolving where there symlink points to, and using the result
  57. ## for bind mount instead.
  58. symlink_level_counter="$(( symlink_level_counter + 1 ))"
  59. true "$fso_ro is a symlink"
  60. fso_real_location="$(realpath "$fso_ro")"
  61. fso_ro="$fso_real_location"
  62. else
  63. true "$fso_ro is not a symlink"
  64. break
  65. fi
  66. if [ "$symlink_level_counter" -ge "$symlink_level_max" ]; then
  67. break
  68. fi
  69. done
  70. true "fso_ro: $fso_ro"
  71. fso_rw="${rw_dest_dir}${fso_ro}"
  72. # Make sure fso_ro is not mounted.
  73. umount "$fso_ro" 2> /dev/null || true
  74. if [ -n "$1" ]; then
  75. true "Umounting $1 only..."
  76. continue
  77. fi
  78. # Initially copy over data directories to /rw if rw directory does not exist.
  79. if [ -d "$fso_ro" ] || [ -f "$fso_ro" ]; then
  80. if ! [ -d "$fso_rw" -o -f "$fso_rw" ]; then
  81. echo "Initializing $rw_dest_dir with files from $fso_ro" >&2
  82. cp --archive --recursive --parents "$fso_ro" "$rw_dest_dir"
  83. fi
  84. else
  85. true "$fso_ro is neither a directory nor a file or does not exist, skipping."
  86. continue
  87. fi
  88. # Bind the fso.
  89. echo "Bind mounting $fso_rw onto $fso_ro" >&2
  90. mount --bind "$fso_rw" "$fso_ro"
  91. done
  92. }
  93. main() {
  94. prerequisite "$@"
  95. init "$@"
  96. legacy "$@"
  97. bind_dirs "$@"
  98. }
  99. for source_folder in /usr/lib/qubes-bind-dirs.d /etc/qubes-bind-dirs.d /rw/config/qubes-bind-dirs.d ; do
  100. true "source_folder: $source_folder"
  101. if [ ! -d "$source_folder" ]; then
  102. continue
  103. fi
  104. for file_name in "$source_folder/"*".conf" ; do
  105. bash -n "$file_name"
  106. source "$file_name"
  107. done
  108. done
  109. main "$@"
  110. true "OK: END."