903727cfd87fcafb324ffd834023542cf3008b54
[tridge/autocluster.git] / config.d / 10shareddisk.defconf
1 # Hey Emacs, this is a -*- shell-script -*- !!!
2
3 ######################################################################
4
5 defconf SHAREDDISKSIZE "10G" \
6         "<n>G" "size of the 3 shared disks"
7
8 defconf SHAREDDISK_COUNT "3" \
9         "<n>" "the number of shared disks"
10
11 defconf SHAREDDISK_TEMPLATE "|shared_disk_template" \
12         "<file>" "libvirt template fragment for shared disks"
13
14 defconf SHARED_DISK_TYPE "virtio" \
15         "scsi|ide|virtio|iscsi" "type of disks to use for shared disks"
16
17 defconf SHARED_DISK_PREFIX "@uto" \
18         "sd|hd|vd" "shared disk device prefix"
19
20 defconf SHARED_DISK_CACHE "default" \
21         "default|none|writeback|writethrough" "shared disk cache type"
22
23 defconf SHARED_DISK_FIRST_SUFFIX "" \
24         "|a|b|..." "override for 1st shared disk suffix - usually calculated by shared_disk_template()"
25
26 defconf SHARED_DISK_MULTIPATH_NUMPATHS "2" \
27         "<n>" "number of paths to create for each shared disk"
28
29 defconf SHARED_DISK_MULTIPATH_CALLOUT "/sbin/scsi_id_autocluster.sh %n" \
30         "<command>" ""
31
32 defconf SHARED_DISK_ID_GEN "shared_disk_id_default" \
33         "<command>" "function/command for creating shared disk ids"
34
35 ##########
36
37 defconf ISCSI_HOST "$GATEWAY" \
38         "<ip-addr>" "host machine serving our iSCSI targets"
39
40 defconf ISCSI_PORT "3260" \
41         "<port>" "port serving our iSCSI targets"
42
43 defconf ISCSI_IQN "iqn.1969-08" \
44         "<string>" "iSCSI qualified name for targets"
45
46 defconf ISCSI_TID "1" \
47         "<num>" "iSCSI target ID"
48
49 defconf ISCSI_DEFAULT_TEMPLATE "$installdir/templates/iSCSI-default" \
50         "<file>" "template for iSCSI default file"
51
52 defconf ISCSI_ST_CONFIG_TEMPLATE "$installdir/templates/iSCSI-st_config" \
53         "<file>" "template for iSCSI st_config file"
54
55
56 ##############################
57
58 shared_disk_template ()
59 {
60     # Don't do anything for iSCSI.
61     [ "$SHARED_DISK_TYPE" != "iscsi" ] || return 0
62
63     local paths="${1:-${SHARED_DISK_MULTIPATH_NUMPATHS}}"
64     local first="${2:-${SHARED_DISK_FIRST_SUFFIX}}"
65
66     if [ -z "$first" ] ; then
67         if [ "$SYSTEM_DISK_PREFIX" = "$SHARED_DISK_PREFIX" ] ; then
68             first="b"
69         else
70             first="a"
71         fi
72     fi
73         
74     local -a devices=($(eval echo {${first}..z} {a..z}{a..z}))
75
76     local p c
77     local n=0
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..."
82             cat <<EOF
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@@'/>
87     </disk>
88 EOF
89             n=$(($n + 1))
90         done
91     done
92 }
93
94 ##############################
95
96 shared_disk_post_config_hook()
97 {
98     if [ "$SHARED_DISK_PREFIX" = "@uto" ] ; then
99         SHARED_DISK_PREFIX=$(rhel_disk_prefix $SHARED_DISK_TYPE)
100     fi
101 }
102
103 register_hook post_config_hooks shared_disk_post_config_hook
104
105 shared_disk_ids="tmp/shared_disk_ids"
106
107 register_hook create_cluster_hooks shared_disk_setup
108
109 shared_disk_setup ()
110 {
111     rm -f "$shared_disk_ids"
112
113     if [ -n "$SHAREDDISKSIZE" -a -n "$SHAREDDISK_TEMPLATE" -a \
114         -n "$SHAREDDISK_COUNT" -a "$SHAREDDISK_COUNT" != 0 ] ; then
115
116         if [ "$SHARED_DISK_TYPE" = "iscsi" ] ; then
117             iscsi_out="tmp/iscsi.${CLUSTER}"  # Global, not local.
118
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
123 EOF
124             local uc=$(echo "$CLUSTER" | tr a-z A-Z)
125         fi
126
127         echo "Creating ${SHAREDDISK_COUNT} shared disks"
128         local i
129         for i in $(seq 1 $SHAREDDISK_COUNT); do
130             local f="$VIRTBASE/$CLUSTER/shared$i"
131             rm -f "$f"
132             if [ "$SHARED_DISK_TYPE" = "iscsi" ] ; then
133                 dd if=/dev/zero seek=$SHAREDDISKSIZE bs=1 count=1 of="$f"
134
135                 local paths=$SHARED_DISK_MULTIPATH_NUMPATHS  # readability
136                 local zc=$(printf "%03d" $i)
137                 local p
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} \
144     -b ${f}
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}
148 EOF
149                 done
150             else
151                 qemu-img create -f raw "$f" $SHAREDDISKSIZE
152             fi
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"
157         done
158         echo
159
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
163         fi
164     else
165         SHAREDDISKSIZE=""
166         SHAREDDISK_TEMPLATE=""
167         SHAREDDISK_COUNT=""
168     fi
169 }
170
171 shared_disk_id_default ()
172 {
173     # Disk number argument is ignored
174     local t="AUTO-$(uuidgen)"
175     # Length of 13 bytes is historical
176     echo "${t:0:13}"
177 }
178
179 install_shared_disk_ids ()
180 {
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"
186     fi
187 }
188
189 register_hook setup_base_hooks install_shared_disk_ids
190
191 ##########
192
193 # Allow other configuration files to override this function but still
194 # use the magic.
195 shared_disk_iscsi_setup_base()
196 {
197     shared_disk_iscsi_setup_base_internal
198 }
199
200 # Override this if you use a different scheme for IP addresses.
201 shared_disk_iscsi_setup_base_get_ip ()
202 {
203     echo "${IPBASE}.${IPNET0}.${IPNUM}"
204 }
205
206 shared_disk_iscsi_setup_base_internal ()
207 {
208     echo "Setting up iSCSI for shared disks"
209
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..
213
214     local idir="/var/lib/iscsi"
215
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"
221
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"
227
228     diskimage ln_s "$dd" "/${sd}/${ISCSI_IQN}.${ISCSI_IQN}.${CLUSTER}:tgtd,${ISCSI_HOST},${ISCSI_PORT},1,default"
229
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
235
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}
239 EOF
240 }
241
242 iscsi_cluster_created ()
243 {
244     cat <<EOF
245
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.
252
253 You may also want to copy these commands somewhere so they are run
254 when $ISCSI_HOST boots (e.g. /etc/rc.local).
255 EOF
256 }