Advertisement
gusibsd

block script

Mar 17th, 2016
139
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.04 KB | None | 0 0
  1. #!/bin/sh -e
  2. #
  3. # FreeBSD hotplug script for attaching disks
  4. #
  5. # Parameters:
  6. # $1: xenstore backend path of the vbd
  7. # $2: action, either "add" or "remove"
  8. #
  9. # Environment variables:
  10. # None
  11. #
  12.  
  13. DIR=$(dirname "$0")
  14. . "${DIR}/hotplugpath.sh"
  15. . "${DIR}/locking.sh"
  16.  
  17.  
  18. ############################################################################
  19. ##
  20. # This set of functions could be used elsewhere and thus should be moved to
  21. # their own script file and be sourced here
  22. #
  23.  
  24. ##
  25. # xenstore_read_default <path> <default>
  26. #
  27. # Read the given path, returning the value there or the given default if the
  28. # path is not present.
  29. #
  30.  
  31. xenstore_read_default() {
  32. xenstore-read "$1" 2>/dev/null || echo "$2"
  33. }
  34.  
  35. ##
  36. # xenstore_read <path>+
  37. #
  38. # Read each of the given paths, returning each result on a separate line, or
  39. # exit this script if any of the paths is missing.
  40. #
  41. xenstore_read() {
  42. local v=$(xenstore-read "$@" || true)
  43. [ "$v" != "" ] || fatal "xenstore-read $@ failed."
  44. echo "$v"
  45. }
  46.  
  47.  
  48. ##
  49. # _xenstore_write (<path> <value>)+
  50. #
  51. # Write each of the key/value pairs to the store.
  52. #
  53. _xenstore_write() {
  54. log debug "Writing $@ to xenstore."
  55. xenstore-write "$@"
  56. }
  57.  
  58. ##
  59. # xenstore_write (<path> <value>)+
  60. #
  61. # Write each of the key/value pairs to the store, and exit this script if any
  62. # such writing fails.
  63. #
  64. xenstore_write() {
  65. _xenstore_write "$@" || fatal "Writing $@ to xenstore failed."
  66. }
  67.  
  68.  
  69. ##
  70. # add x
  71. #
  72. canonicalise_mode(){
  73. local mode="$1"
  74.  
  75. if [ x"w" != x"$(echo $mode|grep -o "w")" ]; then
  76. echo "r"
  77. else
  78. if [ x"!" != x"$(echo $mode|grep -o "!")" ]; then
  79. echo "w"
  80. else
  81. echo "!"
  82. fi
  83. fi
  84. }
  85.  
  86. log() {
  87. local level="$1"
  88. shift
  89. logger -p "daemon.$level" -- "$0:" "$@" || echo "$0 $@" >&2
  90. }
  91.  
  92. ##
  93. # needs $backend to be defined
  94. #
  95.  
  96. fatal() {
  97. _xenstore_write "$backend/hotplug-error" "$*" \
  98. "$backend/hotplug-status" error
  99. log err "$@"
  100. exit 1
  101. }
  102.  
  103.  
  104. ############################################################################
  105.  
  106. ##
  107. # Pre:
  108. # After canonicalise_mode $mode is not null
  109. # Post: If the disk is already in use in another domain, report back that domain
  110. # so we can inform of the domain using the device, if not return 0
  111.  
  112. check_sharing(){
  113. local device=$1
  114. local mode=$(canonicalise_mode $2)
  115. local dom_id=$3
  116. local base_path=$4
  117. local type=$5
  118. local physical_device=$6
  119.  
  120. if [ "$mode" == "w" ]; then
  121. for dom in $(xenstore-list "$base_path/$type")
  122. do
  123. for dev in $(xenstore-list "$base_path/$type/$dom")
  124. do
  125. temp=$(xenstore_read_default "$base_path/$type/$dom/$dev/physical-device" "")
  126. if [ x"$temp" == x"$physical_device" ]; then
  127. # we could think we're done here, but it could be possible we were adding the same disk
  128. # two times in the same domain, the second time we would find the disk in the xenstore and
  129. # think it belongs two another machine. Thus we need to check the dom ids.
  130. if [ "$dom" != "$dom_id" ]; then
  131. echo "$dom"
  132. return
  133. fi
  134. fi
  135. done
  136. done
  137. fi
  138. echo "0"
  139. }
  140.  
  141. ##
  142. # first argument is the device path
  143. # second argument is the action to be performed
  144. # third argument is the device type
  145. # fourth argument is the backend path of the disk
  146. # fifth argument is the disk backend base path (something like
  147. # /local/domain/0/backend/vbd/ where all the domain are listed with
  148. # their corresponding disks)
  149. # sixth argument is the dom_id
  150.  
  151. path=$1
  152. action=$2
  153. type=$3
  154. backend=$4
  155. base_path=$5
  156. dom_id=$6
  157.  
  158. physical_device=$(xenstore-read "$path/params")
  159.  
  160. case $action in
  161. add)
  162. if [ ! -e $physical_device ]; then
  163. fatal "File $physical_device does not exist"
  164. fi
  165.  
  166. # check if the device is a file and is mounted as a memory device (the mount command
  167. # does not show the original device but the block device associated with that file)
  168. # file has to exist or the mdconfig command will not be quiet if the file is not used
  169. # as a memory device
  170.  
  171. if [ x$(mdconfig -l -f $physical_device) != "x" ]; then
  172. if [ x"$(mount | grep -E -o "$(mdconfig -l -f $physical_device).*on")" != "x" ]; then
  173. fatal "File $physical_device already in use as loop device"
  174. fi
  175. fi
  176.  
  177. # check if the device is a block device (either a partition, raw disk, zvol) and is
  178. # already mounted
  179.  
  180. if [ x"$(mount | grep -E -o "$physical_device.*on")" != "x" ]; then
  181. fatal "Block device $physical_device already in use"
  182. fi
  183.  
  184. # check if the device is shareable (that is, if it's plugged on "r" or "!" mode then it can
  185. # straightly used, if it's used in "w" then we need to check whether that device is already
  186. # 
  187.  
  188. mode=$(xenstore-read "$backend/mode")
  189. another_dom=$(check_sharing $path $mode $dom_id $base_path $type $physical_device)
  190.  
  191. if [ $another_dom != "0" ]; then
  192. fatal "The device $physical_device seems to already be in use in domain $another_dom"
  193. fi
  194.  
  195. claim_lock "block"
  196. xenstore-write $path/physical-device $physical_device
  197. release_lock "block"
  198. exit 0
  199. ;;
  200. *)
  201. xenstore-rm $path/physical-device
  202. exit 0
  203. ;;
  204. esac
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement