repost of [PATCH node] ovirt-config-boot - minimal installer for livecd image to local disk [PATCH node] refactor Node local disk usage [PATCH node] auto install and firstboot fixes [PATCH node] get memory info directly from /proc/meminfo [PATCH node] set default swap size to twice the RAM size
Alan Pevec
2008-Dec-15  15:45 UTC
[Ovirt-devel] [PATCH node] ovirt-config-boot - minimal installer for livecd image to local disk
LiveOS folder is copied to /dev/HostVG/Root LVM volume,
kernel,initrd and GRUB are installed to /dev/HostVG/Boot partition.
livecd initrd is modified on the fly to support LVM,
which is not included in initramfs produced by mayflower/mkliveinitrd
Example usage:
ovirt-config-boot "$disk" /live "$bootparam1 $bootparam2"
caller is responsible to issue reboot
Signed-off-by: Alan Pevec <apevec at redhat.com>
---
 Makefile.am               |    1 +
 ovirt-node.spec.in        |    5 ++
 scripts/ovirt-config-boot |  122 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 128 insertions(+), 0 deletions(-)
 create mode 100755 scripts/ovirt-config-boot
diff --git a/Makefile.am b/Makefile.am
index a47beaa..09ba56b 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -27,6 +27,7 @@ EXTRA_DIST =			\
   scripts/collectd.conf.in	\
   scripts/ovirt			\
   scripts/ovirt-awake		\
+  scripts/ovirt-config-boot  \
   scripts/ovirt-config-logging  \
   scripts/ovirt-config-networking \
   scripts/ovirt-config-password \
diff --git a/ovirt-node.spec.in b/ovirt-node.spec.in
index 50b2d18..c634a58 100644
--- a/ovirt-node.spec.in
+++ b/ovirt-node.spec.in
@@ -36,6 +36,7 @@ Requires:       bind-utils
 # qemu-img RPM.
 Requires:       qemu-img
 Requires:       nc
+Requires:       grub
 Requires:       /usr/sbin/crond
 ExclusiveArch:  %{ix86} x86_64
 
@@ -112,6 +113,7 @@ cd -
 %{__install} -d -m0755 %{buildroot}%{_sysconfdir}/logrotate.d
 
 %{__install} -p -m0755 scripts/ovirt-awake %{buildroot}%{_sbindir}
+%{__install} -p -m0755 scripts/ovirt-config-boot %{buildroot}%{_sbindir}
 %{__install} -p -m0755 scripts/ovirt-config-logging %{buildroot}%{_sbindir}
 %{__install} -p -m0755 scripts/ovirt-config-networking %{buildroot}%{_sbindir}
 %{__install} -p -m0755 scripts/ovirt-config-password %{buildroot}%{_sbindir}
@@ -203,6 +205,8 @@ fi
 
 %files stateless
 %defattr(-,root,root,0755)
+%{_sbindir}/ovirt-awake
+%{_sbindir}/ovirt-config-boot
 %{_sbindir}/ovirt-config-logging
 %{_sbindir}/ovirt-config-networking
 %{_sbindir}/ovirt-config-password
@@ -243,6 +247,7 @@ fi
 * Thu Dec 11 2008 Perry Myers <pmyers at redhat.com> - 0.96
 - Subpackage stateful/stateless to separate out functionality for
   embedded Node and Node running as part of already installed OS
+- ovirt-config-* setup scripts for standalone mode
 
 * Thu Sep 11 2008 Chris Lalancette <clalance at redhat.com> - 0.92 0.7
 - Add the ovirt-install- and ovirt-uninstall-node scripts, and refactor
diff --git a/scripts/ovirt-config-boot b/scripts/ovirt-config-boot
new file mode 100755
index 0000000..ad0aeb1
--- /dev/null
+++ b/scripts/ovirt-config-boot
@@ -0,0 +1,122 @@
+#!/bin/bash
+#
+# ovirt-config-boot - configure local boot disk partition
+
+# SYNOPSIS
+# ovirt-config-boot livecd_path bootparams
+#
+#       boot_disk   - boot disk device e.g. /dev/sda
+#
+#       livecd_path - where livecd media is mounted,
+#                     parent of LiveOS and isolinux folders
+#
+#       bootparams  - extra boot parameters like console=...
+#
+
+# Source functions library
+. /etc/init.d/functions
+. /etc/init.d/ovirt-functions
+
+
+# local_boot_install livecd_path bootparams
+#  livecd_path -livecd media
+#  bootparams - extra boot parameters like console=...
+#
+#  copy oVirt Node image to the local LVM /dev/HostVG
+ovirt_boot_setup() {
+    local disk=$1
+    local live=$2
+    local bootparams=$3
+    printf "installing oVirt Node image ... "
+    mount_boot
+    mount_liveos
+    # install oVirt Node image for local boot
+    if [ -e "$live/syslinux" ]; then
+      syslinux=syslinux
+    elif [ -e "$live/isolinux" ]; then
+      syslinux=isolinux
+    else
+      syslinux+    fi
+    rm -rf /boot/grub
+    rm -rf /liveos/LiveOS
+    mkdir -p /boot/grub
+    mkdir -p /liveos/LiveOS
+    cp -p $live/LiveOS/squashfs.img /liveos/LiveOS \
+    && cp -p $live/$syslinux/vmlinuz0 /boot
+    rc=$?
+    if [ $rc -ne 0 ]; then
+      printf "image copy failed\n"
+      return $rc
+    fi
+    # append LVM support to the livecd initramfs
+    tmpdir=$(mktemp -d)
+    cd $tmpdir
+    gzip -dc $live/$syslinux/initrd0.img |
+        cpio -id init sbin/real-init 2> /dev/null
+    init_script=init
+    if [ -e sbin/real-init ]; then
+        # Fedora 10 mkliveinitrd
+        init_script=sbin/real-init
+    fi
+    sed -i '/^\/sbin\/udev.*settle/ a \echo Scanning logical volumes\
+lvm vgscan --ignorelockingfailure\
+echo Activating logical volumes\
+lvm vgchange -ay --ignorelockingfailure HostVG \
+' $init_script
+    # fix emergency shell
+    sed -i 's/^    bash$/    bash < \/dev\/console/' $init_script
+    # do not fail if device node already exists
+    sed -i 's/mknod.*$/& || :/' $init_script
+    mkdir -p bin
+    bit+    if [ -e /lib64 ]; then
+        bit=64
+    fi
+    mkdir -p lib$bit
+    if [ -e /sbin/lvm.static ]; then
+        cp /sbin/lvm.static bin/lvm
+    else
+        cp /sbin/lvm bin
+        # lvm is not static in Fedora
+        cp /lib$bit/libreadline.so.5 /lib$bit/libncurses.so.5 lib$bit
+    fi
+    find $init_script bin/lvm lib$bit -type f |
+        cpio -H newc --quiet -o |
+        gzip -9 |
+        cat $live/$syslinux/initrd0.img - > /boot/initrd0.img
+
+    cat > /boot/grub/grub.conf << EOF
+default=0
+timeout=5
+hiddenmenu
+title oVirt Node
+    root (hd0,0)
+    kernel /vmlinuz0 ro root=/dev/HostVG/Root roottypefs=ext3 liveimg
$bootparams
+    initrd /initrd0.img
+EOF
+    echo "(hd0) $disk" > /boot/grub/device.map
+    ( cd /usr/share/grub/*; cp -p stage? e2fs_stage1_5 /boot/grub )
+    grub --device-map=/boot/grub/device.map > /dev/null <<EOF
+root (hd0,0)
+setup --prefix=/grub (hd0)
+EOF
+    rc=$?
+    if [ $rc -ne 0 ]; then
+        printf "boot loader install failed\n"
+        return $rc
+    fi
+
+    # avoid reboot loops using Cobbler PXE only once
+    # Cobbler XMLRPC post-install trigger (XXX is there cobbler SRV record?):
+    # wget
"http://192.168.50.2/cblr/svc/op/trig/mode/post/system/$(hostname)"
+    #   -O /dev/null
+    sync; sync; sync
+    # caller decides when to reboot
+    rm -rf $tmpdir
+    printf "done.\n"
+}
+
+
+ovirt_boot_setup "$1" "$2" "$3"
+
-- 
1.6.0.4
Alan Pevec
2008-Dec-15  15:45 UTC
[Ovirt-devel] [PATCH node] refactor Node local disk usage
use LVM partitions created by o-c-storage
use file bindmounts for persisted configs
use optional /config from livecd image
support for old and new udev versions
add BOOTIF=link|eth* support
Signed-off-by: Alan Pevec <apevec at redhat.com>
---
 scripts/ovirt           |   22 ---
 scripts/ovirt-early     |  394 ++++++++++++++++-------------------------------
 scripts/ovirt-firstboot |   18 ++-
 scripts/ovirt-functions |  166 ++++++++++++++++----
 4 files changed, 287 insertions(+), 313 deletions(-)
 mode change 100644 => 100755 scripts/ovirt
 mode change 100644 => 100755 scripts/ovirt-post
diff --git a/scripts/ovirt b/scripts/ovirt
old mode 100644
new mode 100755
index 81733a5..e2c406b
--- a/scripts/ovirt
+++ b/scripts/ovirt
@@ -11,28 +11,6 @@
 . /etc/init.d/ovirt-functions
 
 start() {
-    # retrieve config from local OVIRT partition if available
-    ovirt=$(mktemp -d)
-    ovirt_mount $ovirt
-    # /config on OVIRT partition contains persisted /etc files
-    cfg=$ovirt/config
-    if [ -d $cfg/etc ]; then
-      cp -rv $cfg/etc/* /etc
-      restorecon -r /etc
-    fi
-    # and optional Augeas augtool script
-    aug=$cfg/config.aug
-    if [ -f $aug ]; then
-      tmpaug=$(mktemp)
-      cp $aug $tmpaug
-      echo "save" >> $tmpaug
-      augtool < $tmpaug > /dev/null 2>&1
-      if [ $? -eq 0 ]; then
-        printf "$aug applied."
-      fi
-    fi
-    umount $ovirt && rmdir $ovirt
-
     if is_standalone; then
         exit 0
     fi
diff --git a/scripts/ovirt-early b/scripts/ovirt-early
index c09a987..1201ab4 100755
--- a/scripts/ovirt-early
+++ b/scripts/ovirt-early
@@ -10,8 +10,6 @@
 . /etc/init.d/functions
 . /etc/init.d/ovirt-functions
 
-# size of the oVirt partition in megabytes
-OVIRT_SIZE=64
 BONDING_MODCONF_FILE=/etc/modprobe.d/bonding
 AUGTOOL_CONFIG=/var/tmp/augtool-config
 
@@ -48,12 +46,15 @@ configure_from_network() {
                         ovirt-process-config $cfgdb $BONDING_MODCONF_FILE
$AUGTOOL_CONFIG
                         if [ -f $AUGTOOL_CONFIG ]; then
                             echo "Loading remote config"
+                            # avoid bindmount issues with augeas
+                            umount_config
/etc/sysconfig/network-scripts/ifcfg-eth*
                             augtool < $AUGTOOL_CONFIG \
                                 && echo "Remote config
applied" \
                                 || echo "Failed applying remote
config"
                         fi
                         if ls /etc/sysconfig/network-scripts/ifcfg-eth* >
/dev/null 2>&1; then
                             echo "Network interfaces created from remote
config"
+                            ovirt_store_config
/etc/sysconfig/network-scripts/ifcfg-eth*
                             return
                         else
                             echo "Remote config contained no network
interfaces"
@@ -61,6 +62,7 @@ configure_from_network() {
                     else
                         echo "Failed to retrieve configuration
bundle"
                     fi
+                    rm $cfgdb
                 fi
             fi
         fi
@@ -80,14 +82,29 @@ configure_from_network() {
     echo "Default config applied"
 }
 
-# find_disk $bus $serial $live_disk
+# $(get_live_disk)
+# livecd boot disk
+get_live_disk() {
+    local live_dev=/dev/live
+    if [ ! -e $live_dev ]; then
+      # PXE boot
+      live_dev=/dev/loop0
+      live_disk+    else
+      live_part=$(readlink -e $live_dev)
+      live_disk=$(basename $(dirname $(udev_info $live_part path)))
+    fi
+    echo $live_disk
+}
+
+# find_disk $bus $serial
 find_disk() {
     local bus=$1
     local serial=$2
-    local live=$3
+    local live=$(get_live_disk)
     for d in /dev/disk/by-id/{scsi,usb}*; do
       ID_FS_USAGE-      eval $(udevinfo --query env --name $d)
+      eval $(udev_info $d env)
       # ID_FS_USAGE is set for partitions
       if [ -z "$ID_FS_USAGE" -a "$ID_BUS" =
"$bus" ]; then
         if [ -z "$serial" -o "$ID_SERIAL" =
"$serial" ]; then
@@ -104,216 +121,10 @@ find_disk() {
     return 1
 }
 
-# TODO move to ovirt-config-storage
-# local_install $local_boot $local_disk $bootparams
-#  local_boot - 1=install LiveOS and boot loader
-#               0=initialize oVirt partition only
-#  local_disk - local disk to hold the oVirt partition
-#           =usb|scsi[:serial#]
-#  bootparams - extra boot parameters like console-#
-# oVirt partition is a local primary ext2 partition, labeled OVIRT
-# content:
-#  /config - local oVirt configuration (ktab, local admin password)
-#  /boot - boot loader, kernel and initramfs
-#  /LiveOS - oVirt Node compressed livecd image
-
-local_install() {
-    local local_boot=$1
-    local local_disk=$2
-    local bootparams=$3
-    local disk
-    local part
-    local live_part
-    local live_disk
-    local live_dev=/dev/live
-    if [ ! -e $live_dev ]; then
-      # PXE boot
-      live_dev=/dev/loop0
-      live_part=$live_dev
-      live_disk-    else
-      live_part=$(readlink -e $live_dev)
-      live_disk=${live_disk%[1-9]}
-    fi
-    local ovirt_part=$(readlink -e /dev/disk/by-label/$OVIRT_LABEL)
-    local ovirt_disk=${ovirt_part%[1-9]}
-    if [ "$ovirt_disk" = "$ovirt_part" ]; then
-      ovirt_disk-    fi
-    if [ -z "$local_disk" ]; then
-        if [ -z "$ovirt_disk" ]; then
-          return 1
-        fi
-        # ovirt_init not specified, use pre-labeled oVirt partition
-        mode=update
-        disk=$ovirt_disk
-        part=$ovirt_part
-    else
-      case "$local_disk" in
-          =)
-          # empty ovirt_init, use current live image device
-          mode=update
-          disk=$live_disk
-          part=$live_part
-          ;;
-          =scsi*)
-          bus=scsi
-          serial=${local_disk#=scsi:}
-          mode=install
-          ;;
-          =usb*)
-          bus=usb
-          serial=${local_disk#=usb:}
-          mode=install
-          ;;
-          *)
-          return 1
-          ;;
-      esac
-      if [ $mode = "install" ]; then
-        if [ "$serial" = "=$bus" ]; then
-          serial-        fi
-        disk=$(find_disk $bus $serial $live_disk)
-        rc=$?
-        if [ $rc -ne 0 ]; then
-          echo "local disk '$local_disk' not available"
-          return 1
-        fi
-        if [ -n "$ovirt_disk" ]; then
-          if [ "$disk" = "$ovirt_disk" ]; then
-            # local disk contains oVirt partition, select it for update
-            # TODO force reinstall option
-            mode=update
-            part=$ovirt_part
-          else
-            # remove label from oVirt partition, there can be only one
-            e2label $ovirt_part ""
-          fi
-        fi
-      fi
-      if [ "$mode" = "install" ]; then
-        printf "installing $disk..." | tee /dev/console
-        dd if=/dev/zero bs=4096 count=1 of=$disk \
-        && parted -s $disk mklabel msdos \
-        && parted -s $disk mkpart primary ext2 0.0 $OVIRT_SIZE \
-        && partprobe -s $disk
-        if [ $? -ne 0 ]; then
-          echo "$disk partition creation failed"; return 1
-        fi
-        part=${disk}1
-        udevsettle
-        mkfs.ext2 -L $OVIRT_LABEL $part \
-        && tune2fs -c0 -i0 $part
-        if [ $? -ne 0 ]; then
-          echo "$disk ext2 creation failed"; return 1
-        fi
-        # update by-label link manually, mkfs won't trigger udev
-        mkdir -p /dev/disk/by-label
-        ln -sf $part /dev/disk/by-label/$OVIRT_LABEL
-      fi
-    fi
-
-    if [ "$mode" = "update" ]; then
-      printf "updating $disk..." | tee /dev/console
-    fi
-    ovirt=$(mktemp -d)
-    if [ "$part" = "$live_part" ]; then
-      # ovirt_init w/o local disk specified
-      # setup /config on live disk, if writeable
-      # TODO mlabel/e2label (check fs2 type or just blindly try?)
-      mount -r $part $ovirt && mount -o remount,rw $ovirt \
-      && mkdir -p $ovirt/config
-      umount $ovirt && rmdir $ovirt
-      return 0
-    fi
-    live=$(mktemp -d)
-    mount -r $live_dev $live
-    if [ $? -ne 0 ]; then
-      echo "source image mount failed"
-      rmdir $live
-      return 1
-    fi
-    mount $part $ovirt
-    if [ $? -ne 0 ]; then
-      echo "local disk mount failed"
-      umount $live && rmdir $live
-      rmdir $ovirt
-      return 1
-    fi
-    mkdir -p $ovirt/config
-    # update local config using the one embedded in livecd image
-    # TODO admin tool for adding /config into livecd image
-    if [ -d $live/config ]; then
-      cp -rv $live/config/* $ovirt/config \
-      || echo "config copy failed"
-    fi
-
-    if [ $local_boot = 0 ]; then
-      # config update only, cleanup and continue booting
-      umount $ovirt && rmdir $ovirt
-      umount $live && rmdir $live
-    else
-      # install oVirt Node image for local boot
-      if [ -e "$live/syslinux" ]; then
-        syslinux=syslinux
-      elif [ -e "$live/isolinux" ]; then
-        syslinux=isolinux
-      else
-        syslinux-      fi
-      rm -rf $ovirt/boot
-      rm -rf $ovirt/LiveOS
-      mkdir -p $ovirt/boot/grub
-      mkdir -p $ovirt/LiveOS
-      cp -p $live/LiveOS/squashfs.img $ovirt/LiveOS \
-      && cp -p $live/$syslinux/initrd0.img $ovirt/boot \
-      && cp -p $live/$syslinux/vmlinuz0 $ovirt/boot
-      if [ $? -ne 0 ]; then
-        echo "image copy failed"
-        umount $ovirt && rmdir $ovirt
-        umount $live && rmdir $live
-        return 1
-      fi
-      part_num=$(( ${part#$disk} - 1 ))
-      cat > $ovirt/boot/grub/grub.conf << EOF
-default=0
-timeout=2
-hiddenmenu
-title oVirt Node
-    root (hd0,$part_num)
-    kernel /boot/vmlinuz0 ro root=LABEL=OVIRT roottypefs=ext2 liveimg
$bootparams
-    initrd /boot/initrd0.img
-EOF
-      grub-install --root-directory=$ovirt $disk >&2
-      if [ $? -ne 0 ]; then
-        echo "boot loader install failed"
-        umount $ovirt && rmdir $ovirt
-        umount $live && rmdir $live
-        return 1
-      fi
-      # remove 1.5 stages we don't need
-      find $ovirt/boot/grub -name '*_stage1_5' ! -name e2fs_stage1_5 \
-        -exec rm {} \;
-      umount $ovirt && rmdir $ovirt
-      umount $live && rmdir $live
-      # FIXME avoid reboot loops
-      # temp. workaround: sync and wait
-      sync; sync; sync
-      printf "oVirt local installation finished, press Enter to
reboot." \
-        > /dev/console
-      read key
-      if [ "$key" = "debug" ]; then
-        sh > /dev/console 2>&1
-      fi
-      reboot
-    fi
-}
 
 start() {
     # oVirt boot parameters
-    #   BOOTIF=<MAC> (appended by pxelinux)
+    #   BOOTIF=link|eth*|<MAC> (appended by pxelinux)
     #   ovirt_init=usb|scsi[:serial#]
     #   ovirt_vol=BOOT_MB:SWAP_MB:ROOT_MB:CONFIG_MB:LOGGING_MB
     #   ovirt_local_boot
@@ -324,11 +135,14 @@ start() {
     #   syslog=server[:port]
     #   TBD logrotate maxsize
 
-    #   BOOTIF=<MAC> (appended by pxelinux)
+    #   BOOTIF=link|eth*|<MAC> (appended by pxelinux)
     # network boot interface is assumed to be on management network where
     # oVirt Server is reachable
-    # IPAPPEND 2 in pxelinux.cfg appends MAC address of the booting node
-    # e.g. BOOTIF=01-00-16-3e-12-34-57
+    # BOOTIF=<MAC> e.g. BOOTIF=01-00-16-3e-12-34-57
+    # PXELINUX option IPAPPEND 2 in pxelinux.cfg appends MAC address
+    # of the booting node
+    # BOOTIF=link - take first eth for which ethtool reports link
+    # BOOTIF=eth* e.g. BOOTIF=eth0 - use given interface
     bootif 
     #   ovirt_init=usb|scsi[:serial#]
@@ -337,23 +151,23 @@ start() {
     # serial# - select exact disk using serial number, as reported by
     #           udev ID_SERIAL
     # e.g. ovirt_init=usb:Generic_STORAGE_DEVICE_0000145418-0:0
-    ovirt_init+    init 
     #   ovirt_vol=BOOT_MB:SWAP_MB:ROOT_MB:CONFIG_MB:LOGGING_MB
     # local partition sizes in GB
-    ovirt_vol_boot-    ovirt_vol_swap-    ovirt_vol_root-    ovirt_vol_config- 
ovirt_vol_logging+    vol_boot_size+    vol_swap_size+    vol_root_size+   
vol_config_size+    vol_logging_size
     #   ovirt_local_boot
     # install/update oVirt Node image on the local installation target disk
-    ovirt_local_boot=0
+    local_boot=0
 
     #   ovirt_standalone
     # force oVirt Node standalone mode
-    ovirt_standalone=0
+    standalone=0
 
     #   pxelinux format:
ip=<client-ip>:<boot-server-ip>:<gw-ip>:<netmask>
     #   anaconda format: ip=<client-ip> netmask=<netmask>
gateway=<gw-ip>
@@ -376,25 +190,65 @@ start() {
 
     for i in $(cat /proc/cmdline); do
         case $i in
-            BOOTIF=??-??-??-??-??-??-??)
-            i=${i#BOOTIF=??-}
-            bootif=$(grep -il $(echo $i|sed 's/-/:/g')
/sys/class/net/eth*/address|rev|cut -d/ -f2|rev)
+            BOOTIF=*)
+            i=${i#BOOTIF=}
+            case "$i" in
+                eth*)
+                bootif=$i
+                ;;
+                link)
+                for eth in $(cd /sys/class/net; echo eth*); do
+                    if ethtool $eth 2>/dev/null|grep -q "Link detected:
yes"
+                    then
+                        bootif=$eth
+                        break
+                    fi
+                done
+                ;;
+                ??-??-??-??-??-??-??)
+                i=${i#??-}
+                bootif=$(grep -il $(echo $i|sed 's/-/:/g')
/sys/class/net/eth*/address|rev|cut -d/ -f2|rev)
+                ;;
+            esac
             ;;
             ovirt_init*)
-            ovirt_init=${i#ovirt_init}
-            if [ -z "$ovirt_init" ]; then
-              ovirt_init='='
+            i=${i#ovirt_init}
+            if [ -n "$i" ]; then
+                # resolve to disk device
+                case "$i" in
+                    =scsi*)
+                    bus=scsi
+                    i=${i#=scsi}
+                    serial=${i#:}
+                    ;;
+                    =usb*)
+                    bus=usb
+                    i=${i#=usb}
+                    serial=${i#:}
+                    ;;
+                    *)
+                    bus+                    serial+                    ;;
+                esac
+                if [ -n "$bus" ]; then
+                    init=$(find_disk $bus $serial)
+                fi
+            else
+                # 'ovirt_init' without value: grab first disk
+                init=/dev/?da
             fi
             ;;
             ovirt_vol=*)
             i=${i#ovirt_vol=}
-            eval $(printf $i|awk -F: '{print "ovirt_vol_boot="$1;
ovirt_vol_swap="$2; print "ovirt_vol_root="$3; print
"ovirt_vol_config="$4; print "ovirt_vol_logging="$5;}')
+            eval $(printf $i|awk -F: '{print "vol_boot_size="$1;
print "vol_swap_size="$2; print "vol_root_size="$3; print
"vol_config_size="$4; print "vol_logging_size="$5;}')
             ;;
             ovirt_local_boot*)
-            ovirt_local_boot=1
+            local_boot=1
             ;;
             ovirt_standalone*)
-            ovirt_standalone=1
+            standalone=1
+            bootparams="$bootparams $i"
             ;;
             ip=*)
             i=${i#ip=}
@@ -418,41 +272,66 @@ start() {
             ;;
         esac
     done
-    # save boot parameters as defaults for ovirt-config-*
+
     if [ -z "$ip_netmask" ]; then
         ip_netmask=$netmask
     fi
     if [ -z "$ip_gateway" ]; then
         ip_gateway=$gateway
     fi
+    # save boot parameters as defaults for ovirt-config-*
+    params="bootif init vol_boot_size vol_swap_size vol_root_size
vol_config_size vol_logging_size local_boot standalone ip_address ip_netmask
ip_gateway ipv6 syslog_server syslog_port bootparams"
+    mount_config
+    if [ -e $OVIRT_DEFAULTS ]; then
+        # update persisted defaults
+        tmpaug=$(mktemp)
+        for p in $params; do
+            PARAM=$(uc $p)
+            value=$(ptr $p)
+            if [ -n "$value" ] ; then
+                echo "set /files$OVIRT_DEFAULTS/OVIRT_$PARAM
'\"$value\"'" \
+                    >> $tmpaug
+            fi
+        done
+        if [ -s $tmpaug ]; then
+            echo "save" >> $tmpaug
+            # augtool on bindmounted files fails,
+            # so edit file at persistent config root,  /config
+            umount_config $OVIRT_DEFAULTS
+            augtool < $tmpaug > /dev/null
+            rm $tmpaug
+            ovirt_store_config $OVIRT_DEFAULTS
+        fi
+    else
+        # initial startup, dump all ovirt bootparams
+        echo > $OVIRT_DEFAULTS
+        for p in $params; do
+            PARAM=$(uc $p)
+            echo "OVIRT_$PARAM='$(ptr $p)'" >>
$OVIRT_DEFAULTS
+        done
+        ovirt_store_config $OVIRT_DEFAULTS
+    fi
 
-    cat > $OVIRT_DEFAULTS <<EOF
-# configuration defaults from oVirt Node boot parameters
-OVIRT_BOOTIF=$bootif
-OVIRT_INIT=$ovirt_init
-OVIRT_VOL_BOOT_SIZE=$ovirt_vol_boot
-OVIRT_VOL_SWAP_SIZE=$ovirt_vol_swap
-OVIRT_VOL_ROOT_SIZE=$ovirt_vol_root
-OVIRT_VOL_CONFIG_SIZE=$ovirt_vol_config
-OVIRT_VOL_LOGGING_SIZE=$ovirt_vol_logging
-OVIRT_LOCAL_BOOT=$ovirt_local_boot
-OVIRT_STANDALONE=$ovirt_standalone
-OVIRT_IP_ADDRESS=$ip_address
-OVIRT_IP_NETMASK=$ip_netmask
-OVIRT_IP_GATEWAY=$ip_gateway
-OVIRT_IPV6=$ipv6
-OVIRT_SYSLOG_SERVER=$syslog_server
-OVIRT_SYSLOG_PORT=$syslog_port
-EOF
-
-    set -x
-    local_install "$ovirt_local_boot" "$ovirt_init"
"$bootparams"
-    set +x
-    if [ $ovirt_standalone = 0 ]; then
+    if [ $standalone = 0 ]; then
         configure_from_network $bootif
+        if [ -n "$init" ]; then
+            ovirt-config-storage AUTO
+            # initial configuration storage, after /config creation
+            ovirt_store_config \
+                /etc/sysconfig/network-scripts/ifcfg-* \
+                $BONDING_MODCONF_FILE
+            if [ $local_boot = 1 ]; then
+                # local disk installation for managed mode
+                mount_live
+                ovirt-config-boot $init /live "$bootparams"
+                reboot
+            fi
+        fi
     fi
+}
 
-# BEGIN - move to ovirt-config-storage
+scan_for_swap() {
+    # swap partition activation
     # find all of the partitions on the system
 
     # get the system pagesize
@@ -478,7 +357,6 @@ EOF
             swapon $device
         fi
     done
-# END - move to ovirt-config-storage
 }
 
 case "$1" in
diff --git a/scripts/ovirt-firstboot b/scripts/ovirt-firstboot
index 5df49d4..ba565bf 100755
--- a/scripts/ovirt-firstboot
+++ b/scripts/ovirt-firstboot
@@ -35,11 +35,25 @@ start ()
         ovirt-config-networking AUTO
         newrole -r system_r -t virtd_t -- -c 'ovirt-config-storage
AUTO'
         ovirt-config-logging AUTO
-    else
-        ovirt-config-setup
+        if [ "$OVIRT_LOCAL_BOOT" = 1 ]; then
+            mount_live
+            ovirt-config-boot $OVIRT_INIT /live "$OVIRT_BOOTPARAMS"
+            reboot
+        fi
+    elif is_firstboot; then
+        ovirt-config-setup < /dev/console
     fi
 
     plymouth --show-splash
+
+    if mount_config; then
+        umount_config $OVIRT_DEFAULTS
+        augtool > /dev/null <<EOF
+set /files$OVIRT_DEFAULTS/OVIRT_FIRSTBOOT no
+save
+EOF
+        ovirt_store_config $OVIRT_DEFAULTS
+    fi
 }
 
 case "$1" in
diff --git a/scripts/ovirt-functions b/scripts/ovirt-functions
index 271e173..cbce347 100644
--- a/scripts/ovirt-functions
+++ b/scripts/ovirt-functions
@@ -91,45 +91,149 @@ ovirt_setup_libvirtd() {
     fi
 }
 
-ovirt_mount() {
-    if [ -e /dev/disk/by-label/$OVIRT_LABEL ]; then
-      mount -r /dev/disk/by-label/$OVIRT_LABEL $1 \
-        || mount /dev/disk/by-label/$OVIRT_LABEL $1
+md5() {
+  md5sum $1 2>/dev/null | (read MD5 filename; echo $MD5)
+}
+
+# return uppercase value
+uc() {
+    echo $(echo $1|tr '[[:lower:]]' '[[:upper:]]')
+}
+
+# return indirect value
+# non-bashism for ${!var}
+ptr() {
+    local v=$1
+    eval "v=\$$v"
+    echo $v
+}
+
+# mount livecd media
+# e.g. CD /dev/sr0, USB /dev/sda1,
+# PXE /dev/loop0 (loopback ISO)
+mount_live() {
+    if grep -q " /live " /proc/mounts; then
+        return 0
+    fi
+    local live_dev=/dev/live
+    if [ ! -e $live_dev ]; then
+      # PXE boot
+      live_dev=/dev/loop0
+    fi
+    mkdir -p /live
+    mount $live_dev /live
+}
+
+# mount boot partition
+# boot loader + kernel + initrd
+mount_boot() {
+    if grep -q " /boot " /proc/mounts; then
+        return 0
+    fi
+    mkdir -p /boot
+    mount /dev/disk/by-label/BOOT /boot
+}
+
+# mount liveos partition
+# LiveOS/
+mount_liveos() {
+    if grep -q " /liveos " /proc/mounts; then
+        return 0
+    fi
+    mkdir -p /liveos
+    mount /dev/HostVG/Root /liveos
+}
+
+# mount config partition
+# /config for persistance
+mount_config() {
+    if grep -q " /config " /proc/mounts; then
+        return 0
+    fi
+    mkdir -p /config
+    mount /dev/HostVG/Config /config
+    if grep -q " /config " /proc/mounts; then
+        # optional config embedded in the livecd image
+        if [ -e /live/config ]; then
+            cp -rv --update /live/config/* /config
+        fi
+        # bind mount all persisted configs to rootfs
+        for f in $(find /config -type f); do
+            target=${f#/config}
+            if grep -q " $target " /proc/mounts ; then
+                # skip if already bind-mounted
+                true
+            else
+                mount -n --bind $f $target
+            fi
+        done
     else
-      mount -r /dev/live $1 \
-        || mount /dev/live $1
+        # /config is not available
+        return 1
     fi
 }
 
-md5() {
-  md5sum $1 2>/dev/null | (read MD5 filename; echo $MD5)
+# unmount bindmounted config files
+#       umount_config /etc/config /etc/config2 ...
+#
+# Use before running sed -i or augeas against the bindmounted file,
+# Otherwise save fails: https://fedorahosted.org/augeas/ticket/32
+# After file is replaced, call ovirt_store_config /etc/config /etc/config2 ...
+# to bindmount the config file again.
+#
+umount_config() {
+    if grep -q " /config " /proc/mounts; then
+        for f in "$@"; do
+            if grep -q " $f " /proc/mounts ; then
+                umount -n $f
+                # refresh rootfs copy
+                cp /config$f $f
+            fi
+        done
+    fi
 }
 
-# persist configuration to /config on OVIRT partition
+# persist configuration to /config
 #   ovirt_store_config /etc/config /etc/config2 ...
+#   copy to /config and bind-mount back
 ovirt_store_config() {
-    ovirt=$(mktemp -d)
-    ovirt_mount $ovirt
-    cfg=$ovirt/config
-    rw=0
-    printf "store config:"
-    for f in "$@"; do
-       # ignore non-/etc paths
-       if [ $f != ${f#/etc/} ]; then
-           # check if changed
-           if [ "$(md5 $f)" != "$(md5 $cfg$f)" ]; then
-               if [ $rw = 0 ]; then
-                   mount -o remount,rw $ovirt
-                   rw=1
-               fi
-               mkdir -p $cfg$(dirname $f)
-               cp $f $cfg$f
-               printf " $f"
-           fi
-       fi
-    done
-    echo
-    umount $ovirt && rmdir $ovirt
+    if grep -q " /config " /proc/mounts; then
+        printf "storing to /config :"
+        for f in "$@"; do
+            printf " $f"
+            # skip if already bind-mounted
+            if grep -q " $f " /proc/mounts ; then
+                printf " already persisted\n"
+            else
+                mkdir -p /config$(dirname $f)
+                cp -a $f /config$f \
+                && mount -n --bind /config$f $f \
+                || printf " failed to persist\n"
+            fi
+        done
+        echo
+    else
+        printf "warning: persistent config storage not available\n"
+    fi
+}
+
+# compat function to handle different udev versions
+udev_info() {
+    local name=$1
+    local query=$2
+    local out
+
+    # old udev command with shortopts
+    out=$(udevinfo -n $name -q $query)
+    rc=$?
+    if [ $rc -ne 0 ]; then
+        out=$(udevadm info --name=$name --query=$query)
+        rc=$?
+    fi
+    if [ $rc -eq 0 ]; then
+        echo $out
+    fi
+    return $rc
 }
 
 backup_file() {
diff --git a/scripts/ovirt-post b/scripts/ovirt-post
old mode 100644
new mode 100755
-- 
1.6.0.4
Alan Pevec
2008-Dec-15  15:45 UTC
[Ovirt-devel] [PATCH node] auto install and firstboot fixes
* Autoinstall is performed when required boot parameters are specified:
- BOOTIF=link|eth*|01-11-22-33-44-55-66
  for choosing management NIC (IPv4 DHCP is assumed)
- ovirt_init=usb|scsi
  to select a local disk drive to create oVirt LVM volumes
  If ovirt_vol parameter is missing, default volume sizes are used:
  BOOT 50MB
  SWAP 2 * RAM size
  ROOT 256MB
  CONFIG 5MB
  LOGGING 256MB
  DATA rest of the disk
  equivalent is ovirt_vol=50::256:5:256
* Show firstboot menu only once. Firstboot state is stored
in the persistent config storage.
* Use the drive selected by ovirt_init boot parameter.
Signed-off-by: Alan Pevec <apevec at redhat.com>
---
 scripts/ovirt-config-storage |   45 ++++++++++++++++++++++-------------------
 scripts/ovirt-functions      |   36 +++++++++++++++++++++------------
 2 files changed, 47 insertions(+), 34 deletions(-)
diff --git a/scripts/ovirt-config-storage b/scripts/ovirt-config-storage
index e2ddec1..fd877e2 100755
--- a/scripts/ovirt-config-storage
+++ b/scripts/ovirt-config-storage
@@ -28,13 +28,25 @@ check_partition_sizes()
     # or just let the mke2fs failure suffice.
 }
 
-# Find a usable/selected storage device along with its size in bytes.
+get_selected_drive_size()
+{
+    local udi=$(hal-find-by-property --key block.device --string $DRIVE)
+    if [ -z "$udi" ]; then
+        warn "ERROR: selected storage device is not available"
+        return 1
+    fi
+    size=$(hal-get-property --udi "$udi" --key storage.size)
+    SPACE=$(echo "scale=0; $size / (1024 * 1024)" | bc -l)
+    echo "selected device: $DRIVE ($SPACE MB)"
+}
+
+# Find a usable/selected storage device.
 # If there are none, give a diagnostic and return nonzero.
 # If there is just one, e.g., /dev/sda, treat it as selected (see below).
 # and return 0.  If there are two or more, make the user select one
 # or decline.  Upon decline, return nonzero. Otherwise, print the
-# selected name, a space, and its size, then return 0.
-# Sample output: "/dev/sda 320072933376"
+# selected name, then return 0.
+# Sample output: /dev/sda
 get_dev_name()
 {
     local udi_list=$(hal-find-by-capability --capability storage)
@@ -58,20 +70,16 @@ get_dev_name()
             *) warn "block device name $block_dev doesn't start with
'/';" \
                 " skipping"; continue;;
         esac
-        size=$(hal-get-property --udi "$d" --key storage.size)
         test -z "$devices" \
             && devices=$block_dev \
             || devices="$devices $block_dev"
-        test -z "$sizes" \
-            && sizes=$size \
-            || sizes="$sizes $size"
     done
 
     # If there's only one device, use it.
     case $devices in
         '') warn "ERROR: found no usable block device";
return 1;;
         *' '*) ;; # found more than one
-        *) echo "$devices $sizes"; return 0;; # just one
+        *) echo "$devices"; return 0;; # just one
     esac
 
     # There are two or more; make the user choose.
@@ -80,10 +88,7 @@ get_dev_name()
     do
         test "$device" = Abort && return 1
         test -z "$device" && continue
-        # $REPLY is the selected number;
-        # use that to map to the corresponding size.
-        size=$(echo "$sizes"|cut -d' ' -f "$REPLY")
-        echo "$device $size"
+        echo "$device"
         return 0
     done
 }
@@ -91,13 +96,8 @@ get_dev_name()
 do_configure()
 {
     local name_and_size
-    name_and_size=$(get_dev_name) || exit 1
-    set -- $name_and_size
-    DRIVE=$1
-    local n_bytes=$2
-
-    SPACE=$(echo "scale=0; $n_bytes / (1024 * 1024)" | bc -l)
-    echo "selected device: $DRIVE ($SPACE MB)"
+    DRIVE=$(get_dev_name) || exit 1
+    get_selected_drive_size
 
     for i in boot swap root config logging ; do
         uc=$(echo $i|tr '[[:lower:]]' '[[:upper:]]')
@@ -270,10 +270,13 @@ ROOT_SIZE=${OVIRT_VOL_ROOT_SIZE:-$default_root_size}
 CONFIG_SIZE=${OVIRT_VOL_CONFIG_SIZE:-$default_config_size}
 LOGGING_SIZE=${OVIRT_VOL_LOGGING_SIZE:-$default_logging_size}
 
+if [ -n "$OVIRT_INIT" ]; then
+    # if present, use the drive selected with 'ovirt_init' boot
parameter
+    DRIVE=$OVIRT_INIT
+    get_selected_drive_size
+fi
 
 if [ "$1" == "AUTO" ]; then
-    # In "AUTO" mode, OVIRT_INIT should be defined in the
environment.
-    DRIVE=$OVIRT_INIT
     check_partition_sizes
     printf "Partitioning hard disk..."
     perform_partitioning
diff --git a/scripts/ovirt-functions b/scripts/ovirt-functions
index cbce347..766c432 100644
--- a/scripts/ovirt-functions
+++ b/scripts/ovirt-functions
@@ -9,34 +9,44 @@ OVIRT_DEFAULTS=/etc/default/ovirt
 if [ -f $OVIRT_DEFAULTS ]; then
     . $OVIRT_DEFAULTS
 fi
-# fallback defaults when sysconfig is empty
+# fallback when default is empty
 OVIRT_STANDALONE=${OVIRT_STANDALONE:-0}
 
 OVIRT_BACKUP_DIR=/var/lib/ovirt-backup
 
-# is_managed
 # return 1 if oVirt Node is running in standalone mode
 # return 0 if oVirt Node is managed by the oVirt Server
 is_managed() {
     return $OVIRT_STANDALONE
 }
 
-# is_standalone = not is_managed
+# oVirt Node in standalone mode does not try to contact the oVirt Server
 is_standalone() {
     if is_managed; then return 1; else return 0; fi
 }
 
-# is_auto_install
-# return 0 if all required oVirt boot parameters are present
+# perform automatic local disk installation
+# when at least following boot parameters are present:
+# for networking - OVIRT_BOOTIF, management NIC
+#       if other ip bootparams are not specified, IPv4 DHCP is assumed
+# for storage - OVIRT_INIT, local disk to use
+#       if ovirt_vol is not specified, default volume sizes are set
 is_auto_install() {
-    test -n "$OVIRT_BOOTIF" \
-        -a -n "$OVIRT_OVIRT_STANDALONE" \
-        -a -n "$OVIRT_INIT" \
-        -a -n "$OVIRT_VOL_BOOT_SIZE" \
-        -a -n "$OVIRT_VOL_SWAP_SIZE" \
-        -a -n "$OVIRT_VOL_ROOT_SIZE" \
-        -a -n "$OVIRT_VOL_CONFIG_SIZE" \
-        -a -n "$OVIRT_VOL_LOGGING_SIZE"
+    if [ -n "$OVIRT_BOOTIF" -a -n "$OVIRT_INIT" ] ; then
+        return 0
+    else
+        return 1
+    fi
+}
+
+# was firstboot menu already shown?
+# state is stored in persistent config partition
+is_firstboot() {
+    if [ -z "$OVIRT_FIRSTBOOT" -o "$OVIRT_FIRSTBOOT" =
"1" ]; then
+        return 0
+    else
+        return 1
+    fi
 }
 
 # find_srv SERVICE PROTO
-- 
1.6.0.4
Alan Pevec
2008-Dec-15  15:45 UTC
[Ovirt-devel] [PATCH node] get memory info directly from /proc/meminfo
to avoid libvirt dependecy and to drop newrole workaround
for selinux issue with initrc_t
Signed-off-by: Alan Pevec <apevec at redhat.com>
---
 scripts/ovirt-config-setup   |    2 +-
 scripts/ovirt-config-storage |    3 +--
 scripts/ovirt-firstboot      |    2 +-
 3 files changed, 3 insertions(+), 4 deletions(-)
diff --git a/scripts/ovirt-config-setup b/scripts/ovirt-config-setup
index 639b7b8..20dd5ae 100755
--- a/scripts/ovirt-config-setup
+++ b/scripts/ovirt-config-setup
@@ -31,7 +31,7 @@ while true; do
         case "$OPTION" in
             "$NETWORK")  ovirt-config-networking ; break ;;
             "$STORAGE")
-                newrole -r system_r -t virtd_t -- -c ovirt-config-storage ;
+                ovirt-config-storage ;
                 break ;;
             "$LOGGING")  ovirt-config-logging    ; break ;;
             "$PASSWORD") ovirt-config-password   ; break ;;
diff --git a/scripts/ovirt-config-storage b/scripts/ovirt-config-storage
index fd877e2..dd3fab1 100755
--- a/scripts/ovirt-config-storage
+++ b/scripts/ovirt-config-storage
@@ -256,8 +256,7 @@ do_confirm()
     done
 }
 
-MEM_SIZE=$(virsh --readonly -c qemu:///system nodeinfo \
-           | awk '/Memory size/ { print $3 }')
+MEM_SIZE=$(cat /proc/meminfo | awk '/MemTotal:/ { print $2 }')
 case $MEM_SIZE in
     ''|*[^0-9]*) die failed to get system memory size;;
 esac
diff --git a/scripts/ovirt-firstboot b/scripts/ovirt-firstboot
index ba565bf..1f7cf22 100755
--- a/scripts/ovirt-firstboot
+++ b/scripts/ovirt-firstboot
@@ -33,7 +33,7 @@ start ()
 
     if is_auto_install; then
         ovirt-config-networking AUTO
-        newrole -r system_r -t virtd_t -- -c 'ovirt-config-storage
AUTO'
+        ovirt-config-storage AUTO
         ovirt-config-logging AUTO
         if [ "$OVIRT_LOCAL_BOOT" = 1 ]; then
             mount_live
-- 
1.6.0.4
Alan Pevec
2008-Dec-15  15:45 UTC
[Ovirt-devel] [PATCH node] set default swap size to twice the RAM size
---
 scripts/ovirt-config-storage |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/scripts/ovirt-config-storage b/scripts/ovirt-config-storage
index dd3fab1..2fae9fe 100755
--- a/scripts/ovirt-config-storage
+++ b/scripts/ovirt-config-storage
@@ -261,7 +261,7 @@ case $MEM_SIZE in
     ''|*[^0-9]*) die failed to get system memory size;;
 esac
 
-MEM_SIZE=$(echo "scale=0; $MEM_SIZE / 1024" | bc -l)
+MEM_SIZE=$(echo "scale=0; $MEM_SIZE / 1024 * 2" | bc -l)
 SWAP_SIZE=${OVIRT_VOL_SWAP_SIZE:-$MEM_SIZE}
 
 BOOT_SIZE=${OVIRT_VOL_BOOT_SIZE:-$default_boot_size}
-- 
1.6.0.4