3 # To automate the partitioning, pass in the specific fields in this order
4 # ovirt-config-storage [swap size] [boot size] [root size] [logging size] [data size]
6 # All sizes are in megabytes
9 .
/etc
/init.d
/ovirt-functions
12 warn
() { printf '%s: %s\n' "$ME" "$*" >&2; }
13 die
() { warn
"$*"; exit 1; }
15 trap '__st=$?; stop_log; exit $__st' 0
16 trap 'exit $?' 1 2 13 15
18 # check that we're not booted from local storage; if so then exit with an error
19 if is_booted_from_local_disk
; then
20 die
"You cannot configure storage on a running system. Please boot from CD/USB to configure local storage."
23 default_overcommit
=0.5
27 default_logging_size
=2048
28 # -1 indicates data partition should use remaining disk
43 local udi
=$
(hal-find-by-property
--key block.device
--string $drive)
44 # if more than one UDI was found then iterate over them to find the base device
45 if [[ "${udi}" =~ \$
]]; then
46 udi
=$
(echo $udi |
sed 's/\$/ /g')
47 for found
in ${udi}; do
48 if [[ "false" == $
(hal-get-property
--udi $found --key block.is_volume
) ]]; then
54 if [ -z "$udi" ]; then
55 # If hal didn't find the device, it could be a virtio block device
56 # In this case, use sfdisk -s to get the size
57 size
=$
(sfdisk
-s $drive)
58 size
=$
(echo "scale=0; $size * 1024" |
bc -l)
60 size
=$
(hal-get-property
--udi "$udi" --key storage.size
)
61 if [[ "${size}" == "0" ]]; then
62 # disk is probably hot-swappable, use different HAL key
63 # but first check that it is removeable media and that media is present
64 if [[ "true" == "$(hal-get-property --udi "$udi" --key storage.removable.media_available)" ]]; then
65 size
=$
(hal-get-property
--udi "$udi" --key storage.removable.media_size
)
70 size
=$
(echo "scale=0; $size / (1024 * 1024)" |
bc -l)
71 echo "$drive ($size MB)"
72 echo "Disk Identifier: $(basename "$udi")"
73 if [ -n "$space_var" ]; then
78 check_partition_sizes
()
80 local disk_size need_size
82 local min_data_size
=$DATA_SIZE
83 if [ "$DATA_SIZE" = -1 ]; then
88 get_drive_size
$ROOTDRIVE ROOTDRIVESPACE
89 get_drive_size
$HOSTVGDRIVE HOSTVGDRIVESPACE
90 ROOT_NEED_SIZE
=$
(echo "scale=0; $ROOT_SIZE * 2"|
bc -l)
91 HOSTVG_NEED_SIZE
=$
(echo "scale=0;" \
92 "$SWAP_SIZE + $CONFIG_SIZE + $LOGGING_SIZE + $min_data_size" |
bc -l)
94 if [ $ROOTDRIVE == $HOSTVGDRIVE ]; then
96 ROOT_NEED_SIZE
=$
(echo "scale=0; $ROOT_SIZE * 2 + $HOSTVG_NEED_SIZE"|
bc -l)
98 drive_list
="ROOT HOSTVG"
101 for drive
in $drive_list; do
102 drive_need_size
=$
(eval "echo \${$(echo ${drive}_NEED_SIZE)"})
103 drive_disk_size=$(eval "echo \
${$(echo ${drive}DRIVESPACE)"})
105 if [ $drive_need_size -gt $drive_disk_size ]; then
106 local gap_size
=$
(echo "scale=0; $drive_need_size-$drive_disk_size;" |
bc -l)
108 printf "=============================================================\n"
109 printf "The target storage device is too small for the desired sizes:\n"
110 printf " Disk Target: $drive \n"
111 printf " Size of target storage device: $drive_disk_size MB\n"
112 printf " Total storage size to be used: $drive_need_size MB\n"
114 printf "You need an additional $gap_size MB of storage.\n"
118 printf "Required Space : $drive_need_size MB\n\n"
122 # check if an existing HostVG exists on a device other than the target
123 devices
="$(pvs -o pv_name,vg_name --noheadings | \
124 grep "HostVG
"|grep -v $HOSTVGDRIVE|awk '{ print $1 }')"
126 if [ -n "$devices" ]; then
128 printf "There appears to already be an installation on another device:\n"
129 for device
in $devices; do
130 udi
=$
(hal-find-by-property
--key block.device
--string $device)
131 printf "\t$device ($(basename "$udi"))\n"
133 printf "We cannot proceed until either device is removed from the system\n"
134 printf "or until the HostVG volume group is removed.\n"
135 printf "\nTo re-install the node, please select \"Uninstall Node\" from the main\n"
136 printf "menu and then try to partition.\n"
144 # Find a usable/selected storage device.
145 # If there are none, give a diagnostic and return nonzero.
146 # If there is just one, e.g., /dev/sda, treat it as selected (see below).
147 # and return 0. If there are two or more, make the user select one
148 # or decline. Upon decline, return nonzero. Otherwise, print the
149 # selected name, then return 0.
150 # Sample output: /dev/sda
153 local udi_list
=$
(hal-find-by-capability
--capability storage
)
154 if test -z "$udi_list"; then
155 warn
"ERROR: no usable storage devices detected"
159 local d devices sizes
160 for d
in $udi_list; do
161 local drive_type
=$
(hal-get-property
--udi "$d" --key storage.drive_type
)
162 test "X$drive_type" = Xdisk ||
continue
163 local block_dev
=$
(hal-get-property
--udi "$d" --key block.device
)
164 # Must start with a '/'.
167 # we use space as separator
168 warn
"block device name '$block_dev' contains space; skipping";
171 *) warn
"block device name $block_dev doesn't start with '/';" \
172 " skipping"; continue;;
175 && devices
="$block_dev" \
176 || devices
="$devices $block_dev"
179 # FIXME: workaround for detecting virtio block devices
180 devices
="$devices $(ls /dev/vd? 2> /dev/null | xargs)"
181 devices
=$
(echo $devices |
tr ' ' '\n' |
sort -u |
xargs)
183 local num_devices
=$
(echo "$devices" |
wc -w)
184 # If there's only one device, use it.
186 0) warn
"ERROR: found no usable block device"; return 1;;
187 1) echo "$devices"; return 0;;
188 *) ;; # found more than one
191 # There are two or more; make the user choose.
192 # display description for each disk
193 for d
in $devices; do
194 get_drive_size
$d >&2
196 local choices
="$devices Abort"
197 select device
in $choices
199 test "$device" = Abort
&& return 1
200 test -z "$device" && continue
209 printf "\n\nPlease select the disk to use for the Root.\n\n"
210 ROOTDRIVE
=$
(get_dev_name
) ||
return 0
211 get_drive_size
$ROOTDRIVE ROOTDRIVESPACE
213 printf "\n\nPlease select the disk to use for the HostVG.\n\n"
214 HOSTVGDRIVE
=$
(get_dev_name
) ||
return 0
215 get_drive_size
$HOSTVGDRIVE HOSTVGDRIVESPACE
216 echo $HOSTVGDRIVESPACE
218 printf "\n\nPlease configure storage partitions.\n\n"
219 printf "* Enter partition sizes in MB.\n"
220 printf "* A value of 0 indicates the partition should be disabled.\n"
221 printf "* If the partition is enabled, it will have a minimum valid size.\n"
222 printf "* Size remaining value is approximate due to cylinder rounding\n"
223 printf " during partitioning.\n"
224 printf "* For the Data partition, a size of -1 indicates that the\n"
225 printf " partition should use up the remaining space on the disk.\n\n"
228 if ask_yes_or_no
"Use these default values ([Y]es/[N]o)?"; then
232 local space_left
=$HOSTVGDRIVESPACE
233 for part
in swap root config logging data
; do
235 if [ "$part" = "data" ]; then
236 part_regexp
="^\-1|0$"
238 uc
=$
(echo $part|
tr '[[:lower:]]' '[[:upper:]]')
240 eval "size=\$$size_var"
241 min_size_var
=${part}_min_size
242 eval "min_size=\$$min_size_var"
246 read -ep "Change $part partition size. (Def. ${size}MB), Min. ${min_size}MB, Max. ~${space_left}MB? or Q to quit "
248 test -z "$mb_input" && mb_input
=$size
250 if [[ $mb_input == "q" ||
$mb_input == "Q" ]]; then
253 elif [[ $mb_input =~ ^
-*[0-9]+$
]]; then
254 if [[ $mb_input -ge $min_size ||
$mb_input =~
$part_regexp ]] \
255 && [[ $mb_input -le $space_left ]] ; then
256 eval "$size_var=$mb_input"
260 printf "invalid $part size: $mb_input. "
261 printf "Does not fall into specified range.\n"
264 printf "invalid $part size: '$mb_input'.\n"
267 space_left
=$
(echo "scale=0;$space_left - $size_used" |
bc -l)
270 if ! check_partition_sizes
; then
271 printf "Please try partitioning again.\n"
276 # save input variables
278 set /files$OVIRT_DEFAULTS/OVIRT_INIT $ROOTDRIVE
279 set /files$OVIRT_DEFAULTS/OVIRT_VOL_SWAP_SIZE $SWAP_SIZE
280 set /files$OVIRT_DEFAULTS/OVIRT_VOL_ROOT_SIZE $ROOT_SIZE
281 set /files$OVIRT_DEFAULTS/OVIRT_VOL_CONFIG_SIZE $CONFIG_SIZE
282 set /files$OVIRT_DEFAULTS/OVIRT_VOL_LOGGING_SIZE $LOGGING_SIZE
283 set /files$OVIRT_DEFAULTS/OVIRT_VOL_DATA_SIZE $DATA_SIZE
289 if [ -z "$ROOTDRIVE" ]; then
290 printf "\nNo Root storage device selected.\n"
294 local data_size_display
="$DATA_SIZE MB"
295 if [ "$DATA_SIZE" = -1 ]; then
297 if [ $ROOTDRIVE == $HOSTVGDRIVE ]; then
298 local remaining_mb
=$
(( $ROOTDRIVESPACE - $SWAP_SIZE \
299 - $ROOT_SIZE * 2 - $CONFIG_SIZE - $LOGGING_SIZE ))
301 local remaining_mb
=$
(( $HOSTVGDRIVESPACE - $SWAP_SIZE - $CONFIG_SIZE - $LOGGING_SIZE ))
303 data_size_display
="$remaining_mb MB"
308 The local disk will be repartitioned as follows:
309 ================================================
310 Root Drive: $(get_drive_size $ROOTDRIVE)
311 HostVG Drive: $(get_drive_size $HOSTVGDRIVE)
312 Swap partition size: $SWAP_SIZE MB
313 Installation partition size: $ROOT_SIZE * 2 MB
314 Configuration partition size: $CONFIG_SIZE MB
315 Logging partition size: $LOGGING_SIZE MB
316 Data partition size: $data_size_display
321 # cleanup lvms on selected disk
322 # - remove mounted filesystems
323 # - remove LVM volumes and groups
327 for vg
in $
(pvs
-o vg_name
--noheadings $HOSTVGDRIVE* 2>/dev
/null|
sort -u); do
328 wipe_volume_group
$vg
332 perform_partitioning
()
334 log
"Partitioning drive: $ROOTDRIVE"
335 if [ -z "$HOSTVGDRIVE" ]; then
336 printf "\nNo storage device selected.\n"
341 log
"Starting partitioning of $ROOTDRIVE"
343 log
"Saving parameters"
344 unmount_config
/etc
/default
/ovirt
346 log
"Removing old LVM partitions"
349 # begin critical section
352 # FIXME: save a backup copy, just in case?
353 log
"Wiping old boot sector"
354 dd if=/dev
/zero of
=$ROOTDRIVE bs
=1024K count
=1
355 blockdev
--rereadpt $ROOTDRIVE
356 partprobe
-s $ROOTDRIVE
358 MEM_SIZE_MB
=$
(echo "scale=0; $MEM_SIZE_MB / 1024;" |
bc -l)
359 log
"Labeling Drive: $ROOTDRIVE"
360 parted
$ROOTDRIVE -s "mklabel ${LABEL_TYPE}"
361 if [ $ROOTDRIVE != $HOSTVGDRIVE ]; then
362 log
"Labeling Drive: $HOSTVGDRIVE"
363 parted
$HOSTVGDRIVE -s "mklabel ${LABEL_TYPE}"
365 log
"Creating Root and RootBackup Partitions"
366 let RootBackup_end
=${ROOT_SIZE}*2
367 parted
$ROOTDRIVE -s "mkpartfs primary ext2 0M ${ROOT_SIZE}M"
368 parted
$ROOTDRIVE -s "mkpartfs primary ext2 ${ROOT_SIZE}M ${RootBackup_end}M"
369 # sleep to ensure filesystems are created before continuing
371 e2label
${ROOTDRIVE}1 Root
372 e2label
${ROOTDRIVE}2 RootBackup
373 tune2fs
-c 0 -i 0 ${ROOTDRIVE}1
374 tune2fs
-c 0 -i 0 ${ROOTDRIVE}2
375 log
"Creating LVM partition"
377 if [ $ROOTDRIVE == $HOSTVGDRIVE ]; then
378 parted
$HOSTVGDRIVE -s "mkpart primary ext2 ${RootBackup_end}M -1"
381 parted
$HOSTVGDRIVE -s "mkpart primary ext2 0M -1"
384 log
"Toggling LVM on"
385 parted
$HOSTVGDRIVE -s "set $hostvgpart lvm on"
386 parted
$ROOTDRIVE -s "print"
387 udevadm settle
2> /dev
/null || udevsettle
389 # sync GPT to the legacy MBR partitions
390 if [ "gpt" == "$LABEL_TYPE" ]; then
391 log
"Running gptsync to create legacy mbr"
395 partpv
=${HOSTVGDRIVE}${hostvgpart}
396 if [ ! -e "$partpv" ]; then
397 # e.g. /dev/cciss/c0d0p2
398 partpv
=${HOSTVGDRIVE}p
${hostvgpart}
400 log
"Creating physical volume"
401 if [ ! -e "$partpv" ]; then
402 log
"$partpv is not available!"
405 dd if=/dev
/zero of
=${partpv} bs
=1024k count
=1
406 pvcreate
-ff -y "${partpv}"
407 log
"Creating volume group"
408 vgcreate
/dev
/HostVG
"${partpv}"
410 mkdir
-p /dev
/disk
/by-label
412 if [ "$SWAP_SIZE" -gt 0 ]; then
413 log
"Creating swap partition"
414 lvcreate
--name Swap
--size ${SWAP_SIZE}M
/dev
/HostVG
415 mkswap
-L "SWAP" /dev
/HostVG
/Swap
416 echo "/dev/HostVG/Swap swap swap defaults 0 0" >> /etc
/fstab
418 if [ "$CONFIG_SIZE" -gt 0 ]; then
419 log
"Creating config partition"
420 lvcreate
--name Config
--size ${CONFIG_SIZE}M
/dev
/HostVG
421 mke2fs
-j /dev
/HostVG
/Config
-L "CONFIG"
422 tune2fs
-c 0 -i 0 /dev
/HostVG
/Config
424 if [ "$LOGGING_SIZE" -gt 0 ]; then
425 log
"Creating log partition"
426 lvcreate
--name Logging
--size ${LOGGING_SIZE}M
/dev
/HostVG
427 mke2fs
-j /dev
/HostVG
/Logging
-L "LOGGING"
428 tune2fs
-c 0 -i 0 /dev
/HostVG
/Logging
429 echo "/dev/HostVG/Logging /var/log ext3 defaults 0 0" >> /etc
/fstab
433 if [ "$DATA_SIZE" -eq -1 ]; then
434 log
"Creating data partition with remaining free space"
435 lvcreate
--name Data
-l 100%FREE
/dev
/HostVG
437 elif [ "$DATA_SIZE" -gt 0 ]; then
438 log
"Creating data partition"
439 lvcreate
--name Data
--size ${DATA_SIZE}M
/dev
/HostVG
443 if [ "$use_data" = 0 ]; then
444 mke2fs
-j /dev
/HostVG
/Data
-L "DATA"
445 tune2fs
-c 0 -i 0 /dev
/HostVG
/Data
446 echo "/dev/HostVG/Data /data ext3 defaults 0 0" >> /etc
/fstab
447 echo "/data/images /var/lib/libvirt/images bind bind 0 0" >> /etc
/fstab
448 echo "/data/core /var/log/core bind bind 0 0" >> /etc
/fstab
451 # end critical section
454 log
"Mounting config partition"
455 if mount_config
; then
456 ovirt_store_config
/etc
/fstab
460 if [ "$use_data" = 0 ]; then
461 log
"Mounting data partition"
471 if [ -z "$ROOTDRIVE" ]; then
472 printf "\nNo storage device selected.\n"
480 w8
="$w$w$w$w$w$w$w$w"
486 "$wb If you proceed, this will destroy all data on $w" \
487 "$wb your local system, and your hard disk will be $w" \
488 "$wb irreversably reconfigured $w" \
494 if ask_yes_or_no
"Do you wish to proceed ([Y]es/[N]o)?"; then
495 if check_partition_sizes
; then
505 MEM_SIZE_MB
=$
(awk '/MemTotal:/ { print $2 }' /proc
/meminfo
)
507 ''|
*[^
0-9]*) die failed to get system memory size
;;
509 MEM_SIZE_MB
=$
(echo "scale=0; $MEM_SIZE_MB / 1024;" |
bc -l)
511 overcommit
=${OVIRT_OVERCOMMIT:-$default_overcommit}
512 # we multiply the overcommit coefficient by 10 then divide the
513 # product by 10 to avoid decimals in the result
514 OVERCOMMIT_SWAP_SIZE
=$
(echo "scale=0; (${MEM_SIZE_MB} * (${overcommit} * 10))/10;" |
bc -l)
516 # add to the swap the amounts from http://kbase.redhat.com/faq/docs/DOC-15252
517 MEM_SIZE_GB
=$
(echo "scale=0; $MEM_SIZE_MB/1024;" |
bc -l)
518 if [ $MEM_SIZE_GB -le 4 ]; then
520 elif [ $MEM_SIZE_GB -le 16 ]; then
522 elif [ $MEM_SIZE_GB -le 64 ]; then
528 CALC_SWAP_SIZE
=$
(echo "scale=0; ${BASE_SWAP_SIZE} + ${OVERCOMMIT_SWAP_SIZE};" |
bc -l)
530 SWAP_SIZE
=${OVIRT_VOL_SWAP_SIZE:-$CALC_SWAP_SIZE}
531 ROOT_SIZE
=${OVIRT_VOL_ROOT_SIZE:-$default_root_size}
532 CONFIG_SIZE
=${OVIRT_VOL_CONFIG_SIZE:-$default_config_size}
533 LOGGING_SIZE
=${OVIRT_VOL_LOGGING_SIZE:-$default_logging_size}
534 DATA_SIZE
=${OVIRT_VOL_DATA_SIZE:-$default_data_size}
536 if [ -n "$OVIRT_INIT" ]; then
537 # if present, use the drive selected with 'ovirt_init' boot parameter
538 # setting these the same until kernel cmdline argument implemented
539 ROOTDRIVE
=$OVIRT_INIT
540 HOSTVGDRIVE
=$OVIRT_INIT
541 get_drive_size
$ROOTDRIVE ROOTDRIVESPACE
544 # if the node is Fedora then use GPT, otherwise use MBR
545 if [ -f /etc
/fedora-release
]; then
551 if [ "$1" == "AUTO" ]; then
552 log
"Beginning automatic disk partitioning.\n"
553 if [ -n "$OVIRT_INIT" ]; then
554 # do not format if HostVG exists on selected disk...
555 pvs
-o vg_name
--noheadings $HOSTVGDRIVE* 2>/dev
/null|
grep -q -m1 "HostVG"
557 # ... unless overridden by ovirt_firstboot parameter
558 if is_firstboot ||
[ $existingHostVG -ne 0 ]; then
559 if check_partition_sizes
; then
560 log
"Partitioning hard disk..."
564 log
"Skip disk partitioning, HostVG exists"
567 log
"Missing device parameter: unable to partition any disk"
570 OPTIONS
="\"Configure Storage\" \"Review\" \"Commit Changes And Quit\" \"Return To Menu\""
572 PS3
="Choose an option: "
575 printf "\n\n Storage Configuration\n\n" >&2
577 select OPTION
in "$@"
580 "Configure Storage") do_configure
; break ;;
581 "Review") do_review
; break ;;
582 "Commit Changes And Quit") do_confirm
; break ;;
583 "Return To Menu") printf "\nExiting.\n"; exit ;;