Files
libguestfs/appliance/init
Olaf Hering c4b256cebf appliance: only wait for resolv.conf update if dhcpcd succeeded
In case network was requested, but the host lacks both dhclient and
dhcpcd, skip the loop which waits for a resolv.conf update.

This reduces boot time by 10 seconds.

Signed-off-by: Olaf Hering <olaf@aepfle.de>
(cherry picked from commit 4ef645778a)
2024-06-28 10:19:14 +01:00

273 lines
7.5 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/bash
echo Starting /init script ...
PATH=/sbin:/usr/sbin:/bin:/usr/bin
export PATH
# Debian bug 606622.
RUNLEVEL=S
PREVLEVEL=N
export RUNLEVEL PREVLEVEL
# Make sure /tmp /var/tmp are real directories, not symlinks.
if [ ! -d /tmp ] || [ ! -d /var/tmp ]; then
rm -f /tmp /var/tmp
mkdir /tmp /var/tmp
chmod 1777 /tmp /var/tmp
fi
mkdir -p /proc /sys
mount -t proc /proc /proc
mount -t sysfs /sys /sys
# devtmpfs is required since udev 176
mount -t devtmpfs /dev /dev
ln -s /proc/self/fd /dev/fd
# Parse the kernel command line early (must be after /proc is mounted).
cmdline=$(</proc/cmdline)
if [[ $cmdline == *guestfs_verbose=1* ]]; then
guestfs_verbose=1
set -x
fi
if [[ $cmdline == *guestfs_network=1* ]]; then
guestfs_network=1
fi
if [[ $cmdline == *guestfs_rescue=1* ]]; then
guestfs_rescue=1
fi
if [[ $cmdline == *guestfs_noreboot=1* ]]; then
guestfs_noreboot=1
fi
if [[ $cmdline == *guestfs_boot_analysis=1* ]]; then
guestfs_boot_analysis=1
fi
mkdir -p /dev/pts /dev/shm
mount -t devpts /dev/pts /dev/pts
mount -t tmpfs -o mode=1777 shmfs /dev/shm
mkdir -p /sysroot
# taken from initramfs-tools/init --Hilko Bengen
mkdir -p /run
mount -t tmpfs -o "nosuid,size=20%,mode=0755" tmpfs /run
mkdir -p /run/lock
ln -s ../run/lock /var/lock
if [[ $cmdline == *selinux=1* ]]; then
mount -t selinuxfs none /sys/fs/selinux
fi
# On Fedora 23, util-linux creates /etc/mtab in %post .. stupid
# and e2fsprogs fails if the link doesn't exist .. stupid stupid
if ! test -e /etc/mtab; then
ln -s /proc/mounts /etc/mtab
fi
# For openssl (RHBZ#2133884).
if test -d /etc/crypto-policies/back-ends &&
! test -f /etc/crypto-policies/back-ends/opensslcnf.config &&
test -f /usr/share/crypto-policies/DEFAULT/opensslcnf.txt ; then
ln -sf /usr/share/crypto-policies/DEFAULT/opensslcnf.txt /etc/crypto-policies/back-ends/opensslcnf.config
fi
# Static nodes must happen before udev is started.
# Set up kmod static-nodes (RHBZ#1011907).
mkdir -p /run/tmpfiles.d
kmod static-nodes --format=tmpfiles --output=/run/tmpfiles.d/kmod.conf
# Create a machine-id with a random UUID
machine_id=$(dd if=/dev/urandom bs=16 count=1 status=none | od -x -A n)
echo "${machine_id// /}" > /etc/machine-id
# Set up tmpfiles (must run after kmod.conf is created above).
systemd-tmpfiles --prefix=/dev --prefix=/run --prefix=/var/run --create --boot
# Find udevd and run it directly.
for f in /lib/systemd/systemd-udevd /usr/lib/systemd/systemd-udevd \
/sbin/udevd /lib/udev/udevd \
/usr/lib/udev/udevd; do
if [ -x "$f" ]; then UDEVD="$f"; break; fi
done
if [ -z "$UDEVD" ]; then
echo "error: udev not found! Things will probably not work ..."
fi
$UDEVD --daemon #--debug
udevadm trigger
udevadm settle --timeout=600
# Disk optimizations.
# Increase the SCSI timeout so we can read remote images.
shopt -s nullglob
for f in /sys/block/sd*/device/timeout; do echo 300 > $f; done
# https://access.redhat.com/site/solutions/5427
for f in /sys/block/{h,s,ub,v}d*/queue/scheduler; do echo noop > $f; done
shopt -u nullglob
# Set up the network.
ip addr add 127.0.0.1/8 brd + dev lo scope host
ip link set dev lo up
if test "$guestfs_network" = 1; then
iface=$(ls -I all -I default -I lo /proc/sys/net/ipv4/conf)
# Two workarounds for Ubuntu:
touch /etc/fstab
rm -f /etc/dhcp/dhclient-enter-hooks.d/resolved
if dhclient --version >/dev/null 2>&1; then
dhclient $iface
elif dhcpcd $iface; then
# https://github.com/NetworkConfiguration/dhcpcd/issues/258
for i in `seq 0 10`; do
if grep nameserver /etc/resolv.conf; then break; fi
sleep 1
done
fi
fi
# Scan for MDs but don't run arrays unless all expected drives are present
mdadm -As --auto=yes --no-degraded
# Set up a clean LVM environment.
# Empty LVM configuration file means "all defaults".
mkdir -p /tmp/lvm
touch /tmp/lvm/lvm.conf
# If lvm2 supports a "devices file", we need to disable its use
# (RHBZ#1965941).
if command -v lvmdevices || command -v vgimportdevices; then
{
printf 'devices {\n'
printf '\tuse_devicesfile = 0\n'
printf '}\n'
} >> /tmp/lvm/lvm.conf
fi
LVM_SYSTEM_DIR=/tmp/lvm
export LVM_SYSTEM_DIR
lvmetad
# Scan for LVM.
modprobe dm_mod ||:
lvm pvscan --cache --activate ay
# Scan for MDs and run all found arrays even they are in degraded state
mdadm -As --auto=yes --run
# Scan for Windows dynamic disks.
ldmtool create all
# These are useful when debugging.
if test "$guestfs_verbose" = 1 && test "$guestfs_boot_analysis" != 1; then
uname -a
ls -lR /dev
cat /proc/mounts
cat /proc/mdstat
lvm config
lvm pvs
lvm vgs
lvm lvs
ip a
ip r
cat /etc/resolv.conf
lsmod
#hwclock -r
date
echo -n "clocksource: "
cat /sys/devices/system/clocksource/clocksource0/current_clocksource
#ping -n -v -c 5 8.8.8.8
echo -n "uptime: "; cat /proc/uptime
fi
# Run the daemon.
cmd="guestfsd"
eval `grep -Eo 'guestfs_channel=[^[:space:]]+' /proc/cmdline`
if test "x$guestfs_channel" != "x"; then
cmd="$cmd --channel $guestfs_channel"
fi
if test "$guestfs_verbose" = 1; then
cmd="$cmd --verbose"
fi
if test "$guestfs_network" = 1; then
cmd="$cmd --network"
fi
if false; then
# To get a stack trace if the daemon crashes:
# (1) change this section to 'if true'
# (2) add 'gdb' to 'appliance/packagelist.in'
unset LD_PRELOAD
echo set pagination off > /tmp/gdb-script
echo run >> /tmp/gdb-script
echo info registers >> /tmp/gdb-script
echo 'x/16i $pc' >> /tmp/gdb-script
echo t a a bt >> /tmp/gdb-script
echo quit >> /tmp/gdb-script
cmd="gdb -batch -x /tmp/gdb-script --args $cmd"
fi
if ! test "$guestfs_rescue" = 1; then
echo $cmd
$cmd
else
# Run virt-rescue shell.
# We need a daemon, even in virt-rescue.
$cmd &
# XXX This gives a bit of time for virt-rescue to connect to the
# daemon and mount any filesystems.
sleep 2
# Get name of the serial port, from console= passed by libguestfs.
# XXX Consider using /proc/consoles
guestfs_serial=$(grep -Eo 'console=[^[:space:]]+' /proc/cmdline |
sed s/console=//)
# Remove LD_PRELOAD=libSegFault set above.
unset LD_PRELOAD
:> $HOME/.bashrc
grep -Eo 'TERM=[^[:space:]]+' /proc/cmdline >> $HOME/.bashrc
echo "PS1='><rescue> '" >> $HOME/.bashrc
echo "export TERM PS1" >> $HOME/.bashrc
# The shell is opened by default on /dev/console, which (on Linux)
# is not a controlling terminal, causing job control to fail. For
# how we work around this, see:
# https://busybox.net/FAQ.html#job_control
run_bash_with_ctty ()
{
setsid bash -c \
"exec bash </dev/$guestfs_serial >/dev/$guestfs_serial 2>&1"
}
echo
echo "------------------------------------------------------------"
echo
echo "Welcome to virt-rescue, the libguestfs rescue shell."
echo
echo "Note: The contents of / (root) are the rescue appliance."
if ! test -d "/sysroot/dev"; then
echo "You have to mount the guests partitions under /sysroot"
echo "before you can examine them."
else
echo "Use 'cd /sysroot' or 'chroot /sysroot' to see guest filesystems."
fi
echo
run_bash_with_ctty
echo
echo "virt-rescue: Syncing the disk now before exiting ..."
echo
fi
sync
if ! test "$guestfs_noreboot" = 1; then
# qemu has the -no-reboot flag, so issuing a reboot here actually
# causes qemu to exit gracefully.
reboot -f
fi