1 # Hey Emacs, this is a -*- shell-script -*- !!!
3 ######################################################################
5 defconf SHAREDDISKSIZE "10G" \
6 "<n>G" "size of the 3 shared disks"
8 defconf SHAREDDISK_COUNT "3" \
9 "<n>" "the number of shared disks"
11 defconf SHAREDDISK_TEMPLATE "|shared_disk_template" \
12 "<file>" "libvirt template fragment for shared disks"
14 defconf SHARED_DISK_TYPE "virtio" \
15 "scsi|ide|virtio|iscsi" "type of disks to use for shared disks"
17 defconf SHARED_DISK_PREFIX "@uto" \
18 "sd|hd|vd" "shared disk device prefix"
20 defconf SHARED_DISK_CACHE "default" \
21 "default|none|writeback|writethrough" "shared disk cache type"
23 defconf SHARED_DISK_FIRST_SUFFIX "" \
24 "|a|b|..." "override for 1st shared disk suffix - usually calculated by shared_disk_template()"
26 defconf SHARED_DISK_MULTIPATH_NUMPATHS "2" \
27 "<n>" "number of paths to create for each shared disk"
29 defconf SHARED_DISK_MULTIPATH_CALLOUT "/sbin/scsi_id_autocluster.sh %n" \
32 defconf SHARED_DISK_ID_GEN "shared_disk_id_default" \
33 "<command>" "function/command for creating shared disk ids"
37 defconf ISCSI_HOST "$GATEWAY" \
38 "<ip-addr>" "host machine serving our iSCSI targets"
40 defconf ISCSI_PORT "3260" \
41 "<port>" "port serving our iSCSI targets"
43 defconf ISCSI_IQN "iqn.1969-08" \
44 "<string>" "iSCSI qualified name for targets"
46 defconf ISCSI_TID "1" \
47 "<num>" "iSCSI target ID"
49 defconf ISCSI_DEFAULT_TEMPLATE "$installdir/templates/iSCSI-default" \
50 "<file>" "template for iSCSI default file"
52 defconf ISCSI_ST_CONFIG_TEMPLATE "$installdir/templates/iSCSI-st_config" \
53 "<file>" "template for iSCSI st_config file"
56 ##############################
58 shared_disk_template ()
60 # Don't do anything for iSCSI.
61 [ "$SHARED_DISK_TYPE" != "iscsi" ] || return 0
63 local paths="${1:-${SHARED_DISK_MULTIPATH_NUMPATHS}}"
64 local first="${2:-${SHARED_DISK_FIRST_SUFFIX}}"
66 if [ -z "$first" ] ; then
67 if [ "$SYSTEM_DISK_PREFIX" = "$SHARED_DISK_PREFIX" ] ; then
74 local -a devices=($(eval echo {${first}..z} {a..z}{a..z}))
78 for p in $(seq 1 $paths) ; do
79 for c in $(seq 1 $SHAREDDISK_COUNT) ; do
80 local dev="${devices[$n]}"
81 [ -n "$dev" ] || die "Too many shared disks! The function shared_disk_template needs to be hacked to allow more shared disks..."
83 <disk type='file' device='disk'>
84 <driver name='qemu' cache='@@SHARED_DISK_CACHE@@'/>
85 <source file='@@VIRTBASE@@/@@CLUSTER@@/shared${c}'/>
86 <target dev='@@SHARED_DISK_PREFIX@@${dev}' bus='@@SHARED_DISK_TYPE@@'/>
94 ##############################
96 shared_disk_post_config_hook()
98 if [ "$SHARED_DISK_PREFIX" = "@uto" ] ; then
99 SHARED_DISK_PREFIX=$(rhel_disk_prefix $SHARED_DISK_TYPE)
103 register_hook post_config_hooks shared_disk_post_config_hook
105 shared_disk_ids="tmp/shared_disk_ids"
107 register_hook create_cluster_hooks shared_disk_setup
111 rm -f "$shared_disk_ids"
113 if [ -n "$SHAREDDISKSIZE" -a -n "$SHAREDDISK_TEMPLATE" -a \
114 -n "$SHAREDDISK_COUNT" -a "$SHAREDDISK_COUNT" != 0 ] ; then
116 if [ "$SHARED_DISK_TYPE" = "iscsi" ] ; then
117 iscsi_out="tmp/iscsi.${CLUSTER}" # Global, not local.
119 cat <<EOF >"$iscsi_out"
120 tgt-admin --delete tid=${ISCSI_TID} --force
121 tgtadm --lld iscsi --mode target --op new \
122 --tid ${ISCSI_TID} -T ${ISCSI_IQN}.${CLUSTER}:tgtd
124 local uc=$(echo "$CLUSTER" | tr a-z A-Z)
127 echo "Creating ${SHAREDDISK_COUNT} shared disks"
129 for i in $(seq 1 $SHAREDDISK_COUNT); do
130 local f="$VIRTBASE/$CLUSTER/shared$i"
132 if [ "$SHARED_DISK_TYPE" = "iscsi" ] ; then
133 dd if=/dev/zero seek=$SHAREDDISKSIZE bs=1 count=1 of="$f"
135 local paths=$SHARED_DISK_MULTIPATH_NUMPATHS # readability
136 local zc=$(printf "%03d" $i)
138 for p in $(seq 1 $paths) ; do
139 local lun=$(($paths * ($i - 1) + $p))
140 # vendor_id AUTCLSTR used by /etc/init.d/iscsimultipath
141 cat <<EOF >>"$iscsi_out"
142 tgtadm --lld iscsi --mode logicalunit --op new \
143 --tid ${ISCSI_TID} --lun ${lun} \
145 tgtadm --lld iscsi --mode logicalunit --op update \
146 --tid ${ISCSI_TID} --lun ${lun} \
147 --params vendor_id=AUTCLSTR,product_id=${uc},product_rev=0001,scsi_sn=SHARE${zc}
151 qemu-img create -f raw "$f" $SHAREDDISKSIZE
153 # setup a nice ID at the start of the disk
154 "$SHARED_DISK_ID_GEN" "$i" > tmp/diskid
155 dd if=tmp/diskid of=$VIRTBASE/$CLUSTER/shared$i conv=notrunc bs=1 > /dev/null 2>&1
156 head -n 1 tmp/diskid >>"$shared_disk_ids"
160 if [ "$SHARED_DISK_TYPE" = "iscsi" ] ; then
161 register_hook cluster_created_hooks iscsi_cluster_created
162 register_hook setup_base_hooks shared_disk_iscsi_setup_base
166 SHAREDDISK_TEMPLATE=""
171 shared_disk_id_default ()
173 # Disk number argument is ignored
174 local t="AUTO-$(uuidgen)"
175 # Length of 13 bytes is historical
179 install_shared_disk_ids ()
181 if [ -r "$shared_disk_ids" ] ; then
182 local t="/root/scripts/${shared_disk_ids##*/}"
183 echo "Installing shared disk ID file \"${t}\""
184 diskimage mkdir_p "/root/scripts"
185 diskimage put "$shared_disk_ids" "$t"
189 register_hook setup_base_hooks install_shared_disk_ids
193 # Allow other configuration files to override this function but still
195 shared_disk_iscsi_setup_base()
197 shared_disk_iscsi_setup_base_internal
200 # Override this if you use a different scheme for IP addresses.
201 shared_disk_iscsi_setup_base_get_ip ()
203 echo "${IPBASE}.${IPNET0}.${IPNUM}"
206 shared_disk_iscsi_setup_base_internal ()
208 echo "Setting up iSCSI for shared disks"
210 # This simulates what happens when you do something like:
211 # iscsiadm --mode discovery --type sendtargets --portal 10.0.0.1
212 # provided only 1 target is accessible..
214 local idir="/var/lib/iscsi"
216 local dd="${idir}/nodes/${ISCSI_IQN}.${CLUSTER}:tgtd/${ISCSI_HOST},${ISCSI_PORT},1"
217 local d="${dd}/default"
218 diskimage mkdir_p "${dd}"
219 diskimage substitute_vars "$ISCSI_DEFAULT_TEMPLATE" "$d"
220 diskimage chmod 600 "$d"
222 local sd="${idir}/send_targets/${ISCSI_HOST},${ISCSI_PORT}"
223 local s="${sd}/st_config"
224 diskimage mkdir_p "${sd}"
225 diskimage substitute_vars "$ISCSI_ST_CONFIG_TEMPLATE" "$s"
226 diskimage chmod 600 "$s"
228 diskimage ln_s "$dd" "/${sd}/${ISCSI_IQN}.${ISCSI_IQN}.${CLUSTER}:tgtd,${ISCSI_HOST},${ISCSI_PORT},1,default"
230 # After the iscsi initscript is run, new devices for multipath
231 # don't seem to be noticed anymore. This enables an initscript
232 # that ensures that multipath is run when the desired number of
233 # shared disk paths are available.
234 diskimage command /sbin/chkconfig --add iscsimultipath
236 local ip_addr=$(shared_disk_iscsi_setup_base_get_ip)
237 cat <<EOF >>"$iscsi_out"
238 tgtadm --lld iscsi --op bind --mode target --tid ${ISCSI_TID} -I ${ip_addr}
242 iscsi_cluster_created ()
246 This cluster uses iSCSI shared disks for the cluster file system. The
247 commands to configure the iSCSI on the host machine are in the file
248 "${iscsi_out}". You should now run this file on host $ISCSI_HOST
249 using "sh ${iscsi_out}". The first command, which deletes an existing
250 iSCSI target, may fail if there is no existing iSCSI configuration.
251 However, all other commands should succeed.
253 You may also want to copy these commands somewhere so they are run
254 when $ISCSI_HOST boots (e.g. /etc/rc.local).