This file is indexed.

/etc/xen/scripts/block-drbd is in drbd-utils 8.9.2~rc1-2+deb8u1.

This file is owned by root:root, with mode 0o755.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
#!/bin/bash
#
# Copyright (c) 2007 LINBIT Information Technologies GmbH
# Based on the original "block" VBD script by XenSource Inc.
#
# This script implements the "drbd" VBD type. To use a DRBD resource
# as a virtual block device, include a line similar to this in your
# domU configuration:
#
# disk = [ 'drbd:myresource,xvda1,w' ]
#
# This will direct Xen to put the DRBD resource named 'myresource'
# into the Primary role, and configure it as device xvda1 in your
# domU. You may use as many DRBD resources as you like. If you are
# using DRBD in dual-Primary mode (available in DRBD versions 8.0 and
# up), your DRBD-backed domU will be live migration capable. 
#
# IMPORTANT: If you run DRBD in dual-Primary mode with Xen, you MUST
#            ensure that the only time the resource is accessed by
#            both nodes is during domain migration. If you fire up a
#            DRBD-backed domU simultaneously on two nodes, you WILL
#            wreck your VBD data. DO NOT attempt to set up a live
#            migration capable, DRBD-backed domU unless you
#            understand these implications.
#
# This script will not load the DRBD kernel module for you, nor will
# it attach, detach, connect, or disconnect your resource. The init
# script distributed with DRBD will do that for you. Make sure it is
# started before attempting to start a DRBD-backed domU.
#
# Known limitations:
#
# - With 'file' and 'phy' VBD's, Xen will allow one block device to be
#   made available read-only to multiple domU's, or be mounted
#   read-only in the dom0 and be made available read-only to
#   domU's. This is not supported by the 'drbd' VBD type.
# - Tested, thus far, only on Debian etch with Xen 3.0.3.
#
# For more information about DRBD, visit http://www.drbd.org/.
#   
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of version 2.1 of the GNU Lesser General Public
# License as published by the Free Software Foundation.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#

dir=$(dirname "$0")
. "$dir/block-common.sh"

PATH=/usr/sbin:/sbin:$PATH

##
# canonicalise_mode mode
#
# Takes the given mode, which may be r, w, ro, rw, w!, or rw!, or variations
# thereof, and canonicalises them to one of
#
#   'r': perform checks for a new read-only mount;
#   'w': perform checks for a read-write mount; or
#   '!': perform no checks at all.
#
canonicalise_mode()
{
  local mode="$1"

  if ! expr index "$mode" 'w' >/dev/null
  then
    echo 'r'
  elif ! expr index "$mode" '!' >/dev/null
  then
    echo 'w'
  else
    echo '!'
  fi
}


##
# check_sharing device mode
#
# Check whether the device requested is already in use.  To use the device in
# read-only mode, it may be in use in read-only mode, but may not be in use in
# read-write anywhere at all.  To use the device in read-write mode, it must
# not be in use anywhere at all.
#
# Prints one of
#
#    'local': the device may not be used because it is mounted in the current
#             (i.e. the privileged domain) in a way incompatible with the
#             requested mode;
#    'guest': the device may not be used because it already mounted by a guest
#             in a way incompatible with the requested mode; or
#    'ok':    the device may be used.
#
check_sharing()
{
  local dev="$1"
  local mode="$2"

  local devmm=$(device_major_minor "$dev")
  local file

  # Here, different from the original 'block' script, we don't check
  # explicitly for read/write mounts. See "known limitations" above.
  toskip="^$"

  for file in $(cat /proc/mounts | grep -v "$toskip" | cut -f 1 -d ' ')
  do
    if [ -e "$file" ]
    then
      local d=$(device_major_minor "$file")

      if [ "$d" = "$devmm" ]
      then
        echo 'local'
        return
      fi
    fi
  done

  local base_path="$XENBUS_BASE_PATH/$XENBUS_TYPE"
  for dom in $(xenstore-list "$base_path")
  do
    for dev in $(xenstore-list "$base_path/$dom")
    do
      d=$(xenstore_read_default "$base_path/$dom/$dev/physical-device" "")

      if [ "$d" = "$devmm" ]
      then
        # Here, different from the original 'block' script, we don't
        # check explicitly for read/write mounts. See "known
        # limitations" above.
        if ! same_vm $dom
        then
          echo 'guest'
          return
        fi
      fi
    done
  done

  echo 'ok'
}


same_vm()
{
  local otherdom="$1"
  # Note that othervm can be MISSING here, because Xend will be racing with
  # the hotplug scripts -- the entries in /local/domain can be removed by
  # Xend before the hotplug scripts have removed the entry in
  # /local/domain/0/backend/.  In this case, we want to pretend that the
  # VM is the same as FRONTEND_UUID, because that way the 'sharing' will be
  # allowed.
  local othervm=$(xenstore_read_default "/local/domain/$otherdom/vm"         \
                  "$FRONTEND_UUID")

  [ "$FRONTEND_UUID" = "$othervm" ]
}


##
# check_device_sharing dev mode
#
# Perform the sharing check for the given physical device and mode.
#
check_device_sharing()
{
  local dev="$1"
  local mode=$(canonicalise_mode "$2")
  local result

  if [ "x$mode" = 'x!' ]
  then
    return 0
  fi

  result=$(check_sharing "$dev" "$mode")

  if [ "$result" != 'ok' ]
  then
    do_ebusy "Device $dev is mounted " "$mode" "$result"
  fi
}


##
# do_ebusy prefix mode result
#
# Helper function for check_device_sharing check_file_sharing, calling ebusy
# with an error message constructed from the given prefix, mode, and result
# from a call to check_sharing.
#
do_ebusy()
{
  local prefix="$1"
  local mode="$2"
  local result="$3"

  if [ "$result" = 'guest' ]
  then
    dom='a guest '
    when='now'
  else
    dom='the privileged '
    when='by a guest'
  fi

  if [ "$mode" = 'w' ]
  then
    m1=''
    m2=''
  else
    m1='read-write '
    m2='read-only '
  fi

  release_lock "block"
  ebusy \
"${prefix}${m1}in ${dom}domain,
and so cannot be mounted ${m2}${when}."
}


t=$(xenstore_read_default "$XENBUS_PATH/type" 'MISSING')

case "$command" in
  add)
    phys=$(xenstore_read_default "$XENBUS_PATH/physical-device" 'MISSING')
    if [ "$phys" != 'MISSING' ]
    then
      # Depending upon the hotplug configuration, it is possible for this
      # script to be called twice, so just bail.
      exit 0
    fi

    if [ -n "$t" ]
    then
      p=$(xenstore_read "$XENBUS_PATH/params")
      mode=$(xenstore_read "$XENBUS_PATH/mode")
    fi

    case $t in 
      drbd|phy)
        drbd_resource=$p
        drbd_role="$(drbdadm role $drbd_resource)"
        drbd_lrole="${drbd_role%%/*}"
        drbd_dev="$(drbdadm sh-dev $drbd_resource)"
        if [ "$drbd_lrole" != 'Primary' ]; then
          drbdadm primary $drbd_resource
        fi
        dev=$drbd_dev
        FRONTEND_ID=$(xenstore_read "$XENBUS_PATH/frontend-id")
        FRONTEND_UUID=$(xenstore_read_default \
            "/local/domain/$FRONTEND_ID/vm" 'unknown')
        claim_lock "block"
        check_device_sharing "$dev" "$mode"
        write_dev "$dev"
        release_lock "block"
        exit 0
        ;;
      "")
        claim_lock "block"
        success
        release_lock "block"
        ;;
    esac
    ;;

  remove)
    case $t in 
      drbd|phy)
        p=$(xenstore_read "$XENBUS_PATH/params")
        drbd_resource=$p
        drbd_role="$(drbdadm role $drbd_resource)"
        drbd_lrole="${drbd_role%%/*}"
        drbd_dev="$(drbdadm sh-dev $drbd_resource)"

        if [ "$drbd_lrole" != 'Secondary' ]; then
          drbdadm secondary $drbd_resource
        fi
        exit 0
        ;;

      "")
        exit 0
        ;;
    esac
    ;;

esac