2 # z/VM specific functions
4 ################################################################
6 # Copyright (c) 1995-2014 SUSE Linux Products GmbH
8 # This program is free software; you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License version 2 or 3 as
10 # published by the Free Software Foundation.
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with this program (see the file COPYING); if not, write to the
19 # Free Software Foundation, Inc.,
20 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22 ################################################################
24 # z/VM: use default kernel image from local machine
25 # lets go with the default parameters. However zvm_initrd will be a required parameter
26 #zvm_kernel=/boot/image
27 #zvm_initrd=/boot/initrd_worker
28 zvm_param="root=/dev/disk/by-path/ccw-0.0.0150-part1 hvc_iucv=8 console=hvc0"
29 zvm_mult_pass="THR4ME"
30 zvm_init_script="/.build/build"
32 #######################################################################################
34 # this once was in zvm_functions
38 test -n "$ZVM_CLEANUP" && exit 1
43 if test "$1" = "150" -o "$1" = "0150"; then
44 zvm_fatal "don't detach local root"
49 # defining the worker also resets the operating system. Be careful
52 # Note, that this is also limited by the worker definition in the user directory
54 if ! vmcp send $1 define storage ${2}M ; then
55 zvm_fatal "Could not redefine storage of $1 to ${2}M"
61 # kill machine if it already runs
63 # Needs machine name as $1
64 if test -n "$1" ; then
65 if $(vmcp q "$1" >& /dev/null) ; then
69 if ! $(vmcp q "$1" >& /dev/null) ; then
70 if ! $(vmcp xautolog $1 >& /dev/null) ; then
71 zvm_fatal "Could not start machine $1. Is $1 defined in the user directory?"
73 # give the worker a moment to initialize
75 zvm_memset $1 $VM_MEMSIZE
83 # IPL worker. Needs user as $1 and ipl device as $2.
84 if test -n "$1" -a -n "$2" ; then
85 if ! $(vmcp q "$1" >& /dev/null); then
86 zvm_fatal "User $1 not logged on."
88 if ! $(vmcp send $1 ipl $2); then
89 zvm_fatal "Could not send command to $1"
93 zvm_fatal "Not enough arguments for ipl. Need user and device number."
99 # Destroy build. Done by killing the worker machine.
101 if test -n "$1"; then
102 if ! $(vmcp force $1 ) ; then
103 zvm_fatal "Could not force $1"
108 zvm_get_local_devnr() {
109 # $1 is base address, either 150 or 250
110 # $2 is worker number
111 # there is room for up to 100 workers for this controlling guest, however in our setup I expect only up to 10 workers.
112 #echo "Debug: zvm_get_local_devnr: arg1: $1 arg2: $2"
113 if test "$2" -ge 100 ; then
114 zvm_fatal "Not more than 100 workers supported by one controlling guest."
116 if test "$1" = "0150" -o "$1" = "150" ; then
119 if test "$1" = "0250" -o "$1" = "250" ; then
122 zvm_fatal "The disk devices for root and swap must be 150 and 250 respectively."
128 zvm_volume_link_local() {
129 # attach worker disk to local system as preparation for
130 # a) prepare worker for build
131 # b) get rpms of the swap disk after build finished
132 # disk must be detached from worker first
133 # The following arguments are needed:
134 # 1. Worker user name
135 # 2. Worker disk device number
136 # 3. Mult password for the disk
137 # 4. Worker number to generate a uniq local device number
138 if test -n "$4"; then
139 DEVNR=$(zvm_get_local_devnr $2 $4)
140 if ! vmcp link $1 $2 $DEVNR MW pass=THR4ME >& /dev/null ; then
141 zvm_fatal "Could not link disk $2 from user $1 to local device $DEVNR."
143 dasd_configure 0.0.0$DEVNR 1 0 >& /dev/null
145 DEVICE=$(ls /sys/bus/ccw/devices/0.0.0$DEVNR/block/)
146 if ! test -b /dev/${DEVICE}1 ; then
147 zvm_fatal "The device /sys/bus/ccw/devices/0.0.0$DEVNR has not been setup correctly."
151 zvm_fatal "Not enough arguments given to volume_link_local."
155 zvm_volume_detach_local() {
157 # 1. worker device number
159 DEVNR=$(zvm_get_local_devnr $1 $2)
160 prevent_detach $DEVNR
161 dasd_configure 0.0.0$DEVNR 0 0
162 if ! vmcp detach $DEVNR >& /dev/null ; then
163 zvm_fatal "Could not locally detach disk number $1 from worker $2"
167 zvm_volume_attach() {
168 # link the local disk of the worker
170 # $2: disk device number
172 if ! vmcp send $1 link \* $2 $2 ; then
173 zvm_fatal "Could not link remote worker disk number $2 from user $1"
177 zvm_volume_detach() {
178 # send machine detach nr
181 if ! vmcp send $1 detach $2 ; then
182 zvm_fatal "Could not detach disk $2 on worker $1"
187 # 1. Worker user name
188 # 2. Worker root device number
189 # 3. Worker swap device number
190 # 4. Worker number to generate a uniq local device number
192 # - still mounted dasd
195 # - reset worker with force and autolog
196 DEVNR_ROOT=$(zvm_get_local_devnr $2 $4)
197 DEVNR_SWAP=$(zvm_get_local_devnr $3 $4)
198 # First, check for mounts:
199 for DEVNR in $DEVNR_ROOT $DEVNR_SWAP ; do
200 if test -d /sys/bus/ccw/devices/0.0.0$DEVNR/block ; then
201 DEV=$(ls /sys/bus/ccw/devices/0.0.0$DEVNR/block/)
202 echo "Found device of worker $1 available at $DEVNR, device is /dev/$DEV."
203 grep "/dev/$DEV" /proc/mounts >& /dev/null && umount /dev/${DEV}1
206 # Second, check if devices are online
207 for DEVNR in $DEVNR_ROOT $DEVNR_SWAP ; do
208 lsdasd $DEVNR | grep $DEVNR && dasd_configure 0.0.0$DEVNR 0 0
210 # Third, remove stale links
211 for DEVNR in $DEVNR_ROOT $DEVNR_SWAP ; do
212 prevent_detach $DEVNR
213 if vmcp q v $DEVNR 2> /dev/null ; then
217 # Fourth, reset worker
222 modprobe vmcp || zvm_fatal "Cannod load vmcp module"
223 if test -n "$1" ; then
225 start) shift ; zvm_logon "$@" ;;
226 ipl) shift ; zvm_ipl "$@" ;;
227 destroy) shift ; zvm_destroy "$@" ;;
228 volume_attach) shift ; zvm_volume_attach "$@" ;;
229 volume_detach) shift ; zvm_volume_detach "$@" ;;
230 volume_link_local) shift ; zvm_volume_link_local "$@" ;;
231 volume_detach_local) shift ; zvm_volume_detach_local "$@" ;;
232 memset) shift ; zvm_memset "$@" ;;
233 worker_init) shift ; zvm_worker_init "$@" ;;
238 #######################################################################################
240 vm_verify_options_zvm() {
244 VM_SWAPDEV=/dev/dasdb1 # in the vm
246 if test -z "$VM_VOLUME_ROOT" ; then
247 if test -n "$BUILD_ROOT" -a ${#BUILD_ROOT} -le 4 ; then
248 VM_VOLUME_ROOT="$BUILD_ROOT"
250 VM_VOLUME_ROOT="0150"
253 # In z/VM, this is a 4 digit hex number instead of a linux device.
254 # This is the swap disk defined in user direct
255 # This number can be given with the parameter --swap NR.
256 if test -z "$VM_VOLUME_SWAP" ; then
257 if test -n "$VM_SWAP" -a ${#VM_SWAP} -le 4 ; then
258 VM_VOLUME_SWAP="$VM_SWAP"
260 VM_VOLUME_SWAP="0250"
263 # z/VM guest name that is already defined in z/VM
264 if test -z "$VM_WORKER" ; then
265 echo "ERROR: No z/VM worker id specified"
268 if test -z "$VM_WORKER_NR" ; then
269 echo "ERROR: No z/VM worker number specified"
272 # need the name for a kernel in zvm
273 if test -n "$VM_KERNEL" ; then
274 vm_kernel="$VM_KERNEL"
275 elif test -e "/boot/vmlinux.gz" ; then
276 vm_kernel="/boot/vmlinux.gz"
278 echo "ERROR: No z/VM kernel specified"
281 # need the name for an initrd in zvm
282 # this normally will not be the local initrd
283 if test -n "$VM_INITRD" ; then
284 vm_initrd="$VM_INITRD"
286 echo "ERROR: No z/VM initrd specified"
289 zvm_cp worker_init $VM_WORKER $VM_VOLUME_ROOT $VM_VOLUME_SWAP $VM_WORKER_NR
290 zvm_cp volume_detach $VM_WORKER $VM_VOLUME_ROOT
291 zvm_cp volume_detach $VM_WORKER $VM_VOLUME_SWAP
295 # link root/swap to the worker
296 zvm_cp volume_attach $VM_WORKER $VM_VOLUME_ROOT
297 zvm_cp volume_attach $VM_WORKER $VM_VOLUME_SWAP
298 zvm_cp ipl $VM_WORKER $VM_VOLUME_ROOT
300 # IPL needs some time until IPL really starts...
302 # start iucv console. This blocks until build process is finished.
303 iucvconn $VM_WORKER lnxhvc0
304 # sleep some time before taking root and swap devices from worker
305 # This might be critical regarding timing (IUCV_CONSOLE down, but machine still running)
307 zvm_cp volume_detach $VM_WORKER $VM_VOLUME_ROOT
308 zvm_cp volume_detach $VM_WORKER $VM_VOLUME_SWAP
312 if vmcp q "$VM_WORKER" > /dev/null 2>&1 ; then
313 if ! zvm_cp destroy $VM_WORKER ; then
314 echo "could not kill zvm worker $VM_WORKER"
321 # initrd is created in obsstoragesetup.
322 # If it is desired to use a project dependent kernel, use make_guestinitrd from zvm_functions.
323 # have to copy kernel/initrd and run zipl to be able to IPL
324 # have to set init_script before unmounting, thus doing it statically for now.
325 zvm_init_script="/.build/build"
326 mkdir -p $BUILD_ROOT/boot
327 cp $vm_kernel $vm_initrd $BUILD_ROOT/boot
328 mkdir -p $BUILD_ROOT/boot/zipl
329 # finally, install bootloader to the worker disk
330 zipl -t $BUILD_ROOT/boot/zipl -i ${BUILD_ROOT}${vm_kernel} -r ${BUILD_ROOT}${vm_initrd} \
331 --parameters "${zvm_param} init=$zvm_init_script rootfsopts=noatime"
334 vm_attach_root_zvm() {
335 VM_IMAGE=$(ZVM_CLEANUP=1 zvm_cp volume_link_local $VM_WORKER $VM_VOLUME_ROOT $zvm_mult_pass $VM_WORKER_NR )
336 if test "${VM_IMAGE}" = "${VM_IMAGE#dasd}" ; then
337 echo "did not get a real device for VM_IMAGE: $VM_IMAGE"
340 VM_IMAGE="/dev/$VM_IMAGE"
343 vm_attach_swap_zvm() {
344 VM_SWAP=$(ZVM_CLEANUP=1 zvm_cp volume_link_local $VM_WORKER $VM_VOLUME_SWAP $zvm_mult_pass $VM_WORKER_NR )
345 if test "${VM_SWAP}" = "${VM_SWAP#dasd}" ; then
346 echo "did not get a real device for VM_SWAP: $VM_SWAP"
349 VM_SWAP="/dev/$VM_SWAP"
352 vm_detach_root_zvm () {
353 zvm_cp volume_detach_local $VM_VOLUME_ROOT $VM_WORKER_NR
356 vm_detach_swap_zvm() {
357 zvm_cp volume_detach_local $VM_VOLUME_SWAP $VM_WORKER_NR
361 if test -n "$VM_WORKER" -a -n "$VM_WORKER_NR" -a -n "$VM_VOLUME_ROOT" -a -n "$VM_VOLUME_SWAP" ; then
363 (zvm_cp volume_detach $VM_WORKER $VM_VOLUME_ROOT >/dev/null 2>&1)
364 (zvm_cp volume_detach $VM_WORKER $VM_VOLUME_SWAP >/dev/null 2>&1)
365 (zvm_cp volume_detach_local $VM_VOLUME_ROOT $VM_WORKER_NR >/dev/null 2>&1)
366 (zvm_cp volume_detach_local $VM_VOLUME_SWAP $VM_WORKER_NR >/dev/null 2>&1)