>From f2ac659a420bd22bfd69b087cf55edda2de97a11 Mon Sep 17 00:00:00 2001 From: Richard Jones Date: Tue, 26 Jan 2010 10:45:14 +0000 Subject: [PATCH] supermin: Prevent multilib corruption (RHBZ#558593). On some combination of installing, upgrading and removing the base libguestfs package on x86_64, multilib can corrupt libguestfs by leaving a copy of /usr/bin/libguestfs-supermin-helper around which references the wrong architecture (usually, contains links to the i386-based appliance, when the x86_64 appliance should be constructed). This commit changes libguestfs-supermin-helper so that the script is the same on all architectures. Instead, the library passes the differences to the script (eg. $host_cpu). Because the i386 and x86_64 libraries should be at different locations (/usr/lib vs /usr/lib64) this should prevent multilib from screwing things up. Related links: https://bugzilla.redhat.com/show_bug.cgi?id=558593 http://rwmj.wordpress.com/2009/11/16/please-someone-shoot-multilib/#content https://bugzilla.redhat.com/show_bug.cgi?id=235752 --- .gitignore | 1 - appliance/libguestfs-supermin-helper | 123 +++++++++++++++++++++++++++++++ appliance/libguestfs-supermin-helper.in | 95 ------------------------ configure.ac | 2 - src/guestfs.c | 6 +- 5 files changed, 127 insertions(+), 100 deletions(-) create mode 100755 appliance/libguestfs-supermin-helper delete mode 100755 appliance/libguestfs-supermin-helper.in diff --git a/.gitignore b/.gitignore index ee33343..829f807 100644 --- a/.gitignore +++ b/.gitignore @@ -11,7 +11,6 @@ appliance/debian/debirf.conf appliance/initramfs.*.img appliance/initramfs.*.supermin.hostfiles appliance/kmod.whitelist -appliance/libguestfs-supermin-helper appliance/make.sh appliance/packagelist appliance/stamp-debirf-modules diff --git a/appliance/libguestfs-supermin-helper b/appliance/libguestfs-supermin-helper new file mode 100755 index 0000000..0970776 --- /dev/null +++ b/appliance/libguestfs-supermin-helper @@ -0,0 +1,123 @@ +#!/bin/bash - +# Copyright (C) 2009-2010 Red Hat Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +# Helper script which constructs the supermin appliance at runtime. + +unset CDPATH + +set -e + +if [ $# -ne 5 ]; then + p=`basename $0` + echo + echo "$p: Create supermin appliance." + echo + echo "Usage:" + echo "$p sourcedir host_cpu repo kernel initrd" + echo + echo "This script is used by libguestfs to build the supermin appliance" + echo "(kernel and initrd output files). You should NOT need to run this" + echo "program directly except if you are debugging tricky supermin" + echo "appliance problems." + echo + echo "NB: The kernel and initrd parameters are OUTPUT parameters. If" + echo "those files exist, they are overwritten by the output." + echo + echo "Typical usage when debugging supermin appliance problems:" + echo " $p /usr/lib64/guestfs x86_64 fedora-12 /tmp/kernel /tmp/initrd" + echo "Note: This will OVERWRITE any existing files called /tmp/kernel" + echo "and /tmp/initrd." + echo + exit 1 +fi + +# Source directory containing the supermin input files. +sourcedir=$(cd "$1" > /dev/null; pwd) + +# Host CPU and repo constants passed from the library (see: +# https://bugzilla.redhat.com/show_bug.cgi?id=558593). +host_cpu=$2 +repo=$3 + +# Output files. +kernel="$4" +initrd="$5" + +# Kernel: +# Look for the most recent kernel named vmlinuz-*.* which has a +# corresponding directory in /lib/modules/. If the architecture is x86, look +# for any x86 kernel. +# +# RHEL 5 didn't append the arch to the kernel name, so look for kernels +# without arch second. + +arch=$(echo $host_cpu | sed 's/^i.86$/i?86/') +kernels=$( + ls -1dvr /boot/vmlinuz-*.$arch* 2>/dev/null | grep -v xen ||: ; + ls -1dvr /boot/vmlinuz-* 2>/dev/null | grep -v xen +) + +if [ -z "$kernels" ]; then + echo "$0: failed to find a suitable kernel in /boot directory" >&2 + exit 1 +fi + +for f in $kernels; do + b=$(basename "$f") + b=$(echo "$b" | sed 's,vmlinuz-,,') + modpath="/lib/modules/$b" + if [ -d "$modpath" ]; then + ln -sf "$f" "$kernel" + break + fi + modpath= +done + +if [ -z "$modpath" ]; then + echo "$0: failed to find a suitable kernel" >&2 + exit 1 +fi + +# The initrd consists of these components: +# (1) The base skeleton appliance that we constructed at build time. +# name = initramfs.$repo.$host_cpu.supermin.img +# format = compressed cpio +# (2) The modules from modpath which are on the module whitelist. +# format = plain cpio +# (3) The host files which match wildcards in *.supermin.hostfiles. +# format = plain cpio + +cp "$sourcedir"/initramfs.$repo.$host_cpu.supermin.img "$initrd" + +# Kernel modules (2). +exec 5<"$sourcedir"/kmod.whitelist +whitelist= +while read kmod 0<&5; do + whitelist="$whitelist -o -name $kmod" +done +exec 5<&- + +find "$modpath" \( -not -name '*.ko' $whitelist \) -a -print0 | + cpio --quiet -o -0 -H newc >> "$initrd" + +# Host files (3). + +(cd / && \ + ls -1df $( + cat "$sourcedir"/initramfs.$repo.$host_cpu.supermin.hostfiles + ) 2>/dev/null | + cpio -C 65536 --quiet -o -H newc ) >> "$initrd" diff --git a/appliance/libguestfs-supermin-helper.in b/appliance/libguestfs-supermin-helper.in deleted file mode 100755 index ab3aad5..0000000 --- a/appliance/libguestfs-supermin-helper.in +++ /dev/null @@ -1,95 +0,0 @@ -#!/bin/bash - -# @configure_input@ -# Copyright (C) 2009 Red Hat Inc. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -# Helper script which constructs the supermin appliance at runtime. - -unset CDPATH - -set -e - -# Source directory containing the supermin input files. -sourcedir=$(cd "$1" > /dev/null; pwd) - -# Output files. -kernel="$2" -initrd="$3" - -# Kernel: -# Look for the most recent kernel named vmlinuz-*.* which has a -# corresponding directory in /lib/modules/. If the architecture is x86, look -# for any x86 kernel. -# -# RHEL 5 didn't append the arch to the kernel name, so look for kernels -# without arch second. - -arch=$(echo "@host_cpu@" | sed 's/^i.86$/i?86/') -kernels=$( - ls -1dvr /boot/vmlinuz-*.$arch* 2>/dev/null | grep -v xen ||: ; - ls -1dvr /boot/vmlinuz-* 2>/dev/null | grep -v xen -) - -if [ -z "$kernels" ]; then - echo "$0: failed to find a suitable kernel in /boot directory" >&2 - exit 1 -fi - -for f in $kernels; do - b=$(basename "$f") - b=$(echo "$b" | sed 's,vmlinuz-,,') - modpath="/lib/modules/$b" - if [ -d "$modpath" ]; then - ln -sf "$f" "$kernel" - break - fi - modpath= -done - -if [ -z "$modpath" ]; then - echo "$0: failed to find a suitable kernel" >&2 - exit 1 -fi - -# The initrd consists of these components: -# (1) The base skeleton appliance that we constructed at build time. -# name = initramfs.@REPO@.@host_cpu@.supermin.img -# format = compressed cpio -# (2) The modules from modpath which are on the module whitelist. -# format = plain cpio -# (3) The host files which match wildcards in *.supermin.hostfiles. -# format = plain cpio - -cp "$sourcedir"/initramfs.@REPO@.@host_cpu@.supermin.img "$initrd" - -# Kernel modules (2). -exec 5<"$sourcedir"/kmod.whitelist -whitelist= -while read kmod 0<&5; do - whitelist="$whitelist -o -name $kmod" -done -exec 5<&- - -find "$modpath" \( -not -name '*.ko' $whitelist \) -a -print0 | - cpio --quiet -o -0 -H newc >> "$initrd" - -# Host files (3). - -(cd / && \ - ls -1df $( - cat "$sourcedir"/initramfs.@REPO@.@host_cpu@.supermin.hostfiles - ) 2>/dev/null | - cpio -C 65536 --quiet -o -H newc ) >> "$initrd" diff --git a/configure.ac b/configure.ac index 7d71a7d..2edafff 100644 --- a/configure.ac +++ b/configure.ac @@ -717,8 +717,6 @@ AC_CONFIG_FILES([appliance/supermin-split.sh], [chmod +x appliance/supermin-split.sh]) AC_CONFIG_FILES([appliance/supermin-make.sh], [chmod +x appliance/supermin-make.sh]) -AC_CONFIG_FILES([appliance/libguestfs-supermin-helper], - [chmod +x appliance/libguestfs-supermin-helper]) AC_CONFIG_FILES([Makefile src/Makefile fish/Makefile po/Makefile.in examples/Makefile appliance/Makefile diff --git a/src/guestfs.c b/src/guestfs.c index a3d2762..1d6d40b 100644 --- a/src/guestfs.c +++ b/src/guestfs.c @@ -1,5 +1,5 @@ /* libguestfs - * Copyright (C) 2009 Red Hat Inc. + * Copyright (C) 2009-2010 Red Hat Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -1506,9 +1506,11 @@ build_supermin_appliance (guestfs_h *g, const char *path, snprintf (cmd, sizeof cmd, "PATH='%s':$PATH " - "libguestfs-supermin-helper '%s' %s %s", + "libguestfs-supermin-helper '%s' " host_cpu " " REPO " %s %s", path, path, *kernel, *initrd); + if (g->verbose) + print_timestamped_message (g, "%s", cmd); r = system (cmd); if (r == -1 || WEXITSTATUS(r) != 0) { -- 1.6.5.2