bind-dirs.sh 3.5 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. set -x
  26. prerequisite() {
  27. qubes_vm_persistence="$(qubesdb-read /qubes-vm-persistence)"
  28. if [ ! "$qubes_vm_persistence" = "rw-only" ]; 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. }
  38. legacy() {
  39. if [ -d /rw/srv/qubes-whonix ]; then
  40. mv /rw/srv/qubes-whonix /rw/bind-dirs || true
  41. fi
  42. if [ -d /rw/srv/whonix ]; then
  43. mv /rw/srv/whonix /rw/bind-dirs || true
  44. fi
  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. ## For more discussion and symlink and other special files, see:
  55. ## https://phabricator.whonix.org/T414
  56. while true; do
  57. if [ -h "$fso_ro" ]; then
  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 "10" ]; 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" ]; then
  80. if [ ! -d "$fso_rw" ]; then
  81. cp --archive --recursive --parents "$fso_ro" "$rw_dest_dir"
  82. fi
  83. elif [ -f "$fso_ro" ]; then
  84. if [ ! -f "$fso_rw" ]; then
  85. cp --archive --recursive "$fso_ro" "$fso_rw"
  86. fi
  87. else
  88. true "$fso_ro is neither a directory nor a file or does not exist, skipping."
  89. continue
  90. fi
  91. # Bind the fso.
  92. mount --bind "$fso_rw" "$fso_ro"
  93. done
  94. }
  95. main() {
  96. prerequisite "$@"
  97. init "$@"
  98. legacy "$@"
  99. bind_dirs "$@"
  100. }
  101. for source_folder in /usr/lib/qubes-bind-dirs.d /etc/qubes-bind-dirs.d /rw/config/qubes-bind-dirs.d ; do
  102. true "source_folder: $source_folder"
  103. if [ ! -d "$source_folder" ]; then
  104. continue
  105. fi
  106. for file_name in "$source_folder/"*".conf" ; do
  107. bash -n "$file_name"
  108. source "$file_name"
  109. done
  110. done
  111. main "$@"