mirror of
https://github.com/libguestfs/libguestfs.git
synced 2026-03-22 07:03:38 +00:00
Work around this issue with dhcpcd:
https://github.com/NetworkConfiguration/dhcpcd/issues/258
Fixes: commit 0e37e5feea
274 lines
7.5 KiB
Bash
Executable File
274 lines
7.5 KiB
Bash
Executable File
#!/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
|
||
else
|
||
dhcpcd $iface
|
||
# 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 guest’s 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
|