[Ovirt-devel] [PATCH node] refactor Node local disk usage

Alan Pevec apevec at redhat.com
Mon Dec 15 15:45:44 UTC 2008


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




More information about the ovirt-devel mailing list