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. if [ -f "/var/run/qubes-service/qubes-dvm" ]; then
  33. # https://github.com/QubesOS/qubes-issues/issues/1328#issuecomment-169483029
  34. # Do none of the following in a DispVM.
  35. # During DispVM savefile generation, 'qubesdb-read /qubes-vm-persistence'
  36. # outputs 'rw'.
  37. exit 0
  38. fi
  39. }
  40. init() {
  41. [ -n "$rw_dest_dir" ] || rw_dest_dir="/rw/bind-dirs"
  42. [ -n "$symlink_level_max" ] || symlink_level_max="10"
  43. mkdir --parents "$rw_dest_dir"
  44. shopt -s nullglob
  45. shopt -s dotglob
  46. }
  47. legacy() {
  48. true
  49. }
  50. bind_dirs() {
  51. ## legend
  52. ## fso: file system object
  53. ## ro: read-only
  54. ## rw: read-write
  55. for fso_ro in ${binds[@]}; do
  56. local symlink_level_counter
  57. symlink_level_counter="0"
  58. while true; do
  59. if [ -h "$fso_ro" ]; then
  60. ## Resolving where there symlink points to, and using the result
  61. ## for bind mount instead.
  62. symlink_level_counter="$(( symlink_level_counter + 1 ))"
  63. true "$fso_ro is a symlink"
  64. fso_real_location="$(realpath "$fso_ro")"
  65. fso_ro="$fso_real_location"
  66. else
  67. true "$fso_ro is not a symlink"
  68. break
  69. fi
  70. if [ "$symlink_level_counter" -ge "$symlink_level_max" ]; then
  71. break
  72. fi
  73. done
  74. true "fso_ro: $fso_ro"
  75. fso_rw="${rw_dest_dir}${fso_ro}"
  76. # Make sure fso_ro is not mounted.
  77. umount "$fso_ro" 2> /dev/null || true
  78. if [ -n "$1" ]; then
  79. true "Umounting $1 only..."
  80. continue
  81. fi
  82. # Initially copy over data directories to /rw if rw directory does not exist.
  83. if [ -d "$fso_ro" ] || [ -f "$fso_ro" ]; then
  84. cp --verbose --no-clobber --archive --recursive --parents "$fso_ro" "$rw_dest_dir"
  85. else
  86. true "$fso_ro is neither a directory nor a file or does not exist, skipping."
  87. continue
  88. fi
  89. # Bind the fso.
  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."