#!/bin/bash
#%stage: block
#
#%modules: dm-mod
#
#%udevmodules: virtio_blk
#%udevmodules: virtio_console
#%udevmodules: virtio_net
#%udevmodules: virtio_pci
#%udevmodules: virtio_scsi
#%udevmodules: sg
#%udevmodules: sd_mod
#%udevmodules: sr_mod
#%udevmodules: 
#%udevmodules: loop
#%udevmodules: 
#%udevmodules: 9p
#%udevmodules: btrfs
#%udevmodules: cramfs
#%udevmodules: cuse
#%udevmodules: ext2
#%udevmodules: ext3
#%udevmodules: ext4
#%udevmodules: fat
#%udevmodules: fuse
#%udevmodules: hfs
#%udevmodules: hfsplus
#%udevmodules: isofs
#%udevmodules: jfs
#%udevmodules: minix
#%udevmodules: nfs
#%udevmodules: quota
#%udevmodules: reiserfs
#%udevmodules: squashfs
#%udevmodules: squashfs3
#%udevmodules: udf
#%udevmodules: ufs
#%udevmodules: vfat
#%udevmodules: xfs
#%udevmodules: 
#%udevmodules: mac-celtic
#%udevmodules: mac-centeuro
#%udevmodules: mac-croatian
#%udevmodules: mac-cyrillic
#%udevmodules: mac-gaelic
#%udevmodules: mac-greek
#%udevmodules: mac-iceland
#%udevmodules: mac-inuit
#%udevmodules: mac-roman
#%udevmodules: mac-romanian
#%udevmodules: mac-turkish
#%udevmodules: nls_ascii
#%udevmodules: nls_cp1250
#%udevmodules: nls_cp1251
#%udevmodules: nls_cp1255
#%udevmodules: nls_cp437
#%udevmodules: nls_cp737
#%udevmodules: nls_cp775
#%udevmodules: nls_cp850
#%udevmodules: nls_cp852
#%udevmodules: nls_cp855
#%udevmodules: nls_cp857
#%udevmodules: nls_cp860
#%udevmodules: nls_cp861
#%udevmodules: nls_cp862
#%udevmodules: nls_cp863
#%udevmodules: nls_cp864
#%udevmodules: nls_cp865
#%udevmodules: nls_cp866
#%udevmodules: nls_cp869
#%udevmodules: nls_cp874
#%udevmodules: nls_cp932
#%udevmodules: nls_cp936
#%udevmodules: nls_cp949
#%udevmodules: nls_cp950
#%udevmodules: nls_euc-jp
#%udevmodules: nls_iso8859-1
#%udevmodules: nls_iso8859-13
#%udevmodules: nls_iso8859-14
#%udevmodules: nls_iso8859-15
#%udevmodules: nls_iso8859-2
#%udevmodules: nls_iso8859-3
#%udevmodules: nls_iso8859-4
#%udevmodules: nls_iso8859-5
#%udevmodules: nls_iso8859-6
#%udevmodules: nls_iso8859-7
#%udevmodules: nls_iso8859-9
#%udevmodules: nls_koi8-r
#%udevmodules: nls_koi8-ru
#%udevmodules: nls_koi8ru
#%udevmodules: nls_koi8-u
#%udevmodules: nls_utf8
#%udevmodules: 
#%udevmodules: af_packet
#%udevmodules: nfs
#%udevmodules: nfsv2
#%udevmodules: nfsv3
#%udevmodules: nfsv4
#
#%udevmodules: dm-crypt
#
#%udevmodules: ablk_helper
#%udevmodules: aes-i586
#%udevmodules: aes-x86_64
#%udevmodules: aes_s390
#%udevmodules: aesni-intel
#%udevmodules: af_alg
#%udevmodules: algif_hash
#%udevmodules: algif_skcipher
#%udevmodules: ansi_cprng
#%udevmodules: anubis
#%udevmodules: arc4
#%udevmodules: asymmetric_keys
#%udevmodules: async_memcpy
#%udevmodules: async_pq
#%udevmodules: async_raid6_recov
#%udevmodules: async_tx
#%udevmodules: async_xor
#%udevmodules: authenc
#%udevmodules: authencesn
#%udevmodules: blowfish-x86_64
#%udevmodules: blowfish_common
#%udevmodules: blowfish_generic
#%udevmodules: camellia-aesni-avx-x86_64
#%udevmodules: camellia-x86_64
#%udevmodules: camellia_generic
#%udevmodules: cast5-avx-x86_64
#%udevmodules: cast5_generic
#%udevmodules: cast6-avx-x86_64
#%udevmodules: cast6_generic
#%udevmodules: cast_common
#%udevmodules: cbc
#%udevmodules: ccm
#%udevmodules: cmac
#%udevmodules: crc32
#%udevmodules: crc32-pclmul
#%udevmodules: crc32c-intel
#%udevmodules: cryptd
#%udevmodules: crypto_null
#%udevmodules: crypto_user
#%udevmodules: ctr
#%udevmodules: cts
#%udevmodules: deflate
#%udevmodules: des_generic
#%udevmodules: des_s390
#%udevmodules: ecb
#%udevmodules: fcrypt
#%udevmodules: gcm
#%udevmodules: geode-aes
#%udevmodules: gf128mul
#%udevmodules: ghash-clmulni-intel
#%udevmodules: ghash-generic
#%udevmodules: glue_helper
#%udevmodules: hifn_795x
#%udevmodules: khazad
#%udevmodules: lrw
#%udevmodules: lz4
#%udevmodules: lz4hc
#%udevmodules: md4
#%udevmodules: md5
#%udevmodules: michael_mic
#%udevmodules: padlock-aes
#%udevmodules: padlock-sha
#%udevmodules: pcbc
#%udevmodules: pcrypt
#%udevmodules: prng
#%udevmodules: public_key
#%udevmodules: raid6test
#%udevmodules: rmd128
#%udevmodules: rmd160
#%udevmodules: rmd256
#%udevmodules: rmd320
#%udevmodules: rsa
#%udevmodules: salsa20-i586
#%udevmodules: salsa20-x86_64
#%udevmodules: salsa20_generic
#%udevmodules: seed
#%udevmodules: seqiv
#%udevmodules: serpent-avx-x86_64
#%udevmodules: serpent-sse2-i586
#%udevmodules: serpent-sse2-x86_64
#%udevmodules: serpent_generic
#%udevmodules: sha1-ssse3
#%udevmodules: sha1_generic
#%udevmodules: sha1_s390
#%udevmodules: sha256-ssse3
#%udevmodules: sha256_generic
#%udevmodules: sha256_s390
#%udevmodules: sha512-ssse3
#%udevmodules: sha512_generic
#%udevmodules: sha512_s390
#%udevmodules: sha_common
#%udevmodules: tea
#%udevmodules: tgr192
#%udevmodules: twofish-avx-x86_64
#%udevmodules: twofish-i586
#%udevmodules: twofish-x86_64
#%udevmodules: twofish-x86_64-3way
#%udevmodules: twofish_common
#%udevmodules: vmac
#%udevmodules: wp512
#%udevmodules: x509_key_parser
#%udevmodules: xcbc
#%udevmodules: xor
#%udevmodules: xts
#%udevmodules: zlib
#
#%programs: mdadm
#%programs: modprobe
#%programs: lvm
#%programs: grep
#%programs: ln
#%programs: ls
#%programs: head
#%programs: cat
#%programs: ip
#%programs: date
#%programs: valgrind
#%programs: find
#%programs: xargs
#%programs: setctsid
# mount-rootfs-and-do-chroot.sh
#%programs: mkdir
#%programs: stat
#%programs: mount
#%programs: chroot
#%programs: umount
#
#%programs: bc
#%programs: fdisk
#
# Generated at build time:
#@GUESTFS_EXT_CMDS@
#
missing_commands="@GUESTFS_MISSING_CMDS@"

# Make the modules available now
# run_all.sh will load them after this script is sourced
load_modules

# load various modules for cryptsetup
for i in 512 384 256 224 1
do
	modprobe -v sha$i
done

ln -sfbn ../proc/self/mounts /etc/mtab

# from libguestfs-1.19.34/appliance/init:

# Disk optimizations.
# Increase the SCSI timeout so we can read remote images.
for f in /sys/block/sd*/device/timeout; do if test -w $f ; then echo 300 > $f; fi; done
# https://access.redhat.com/site/solutions/5427
for f in /sys/block/{h,s,ub,v}d*/queue/scheduler; do if test -w $f ; then echo noop > $f; fi; done

# Disable ipv6 because host names resolve to ipv4 and ipv6
# Resolver may prefer ipv6 and qemu usernet does only ipv4
for f in /proc/sys/net/ipv6/conf/*/disable_ipv6
do
	if test -w $f
	then
		echo 1 > $f
	fi
done

# Set up the network.
ip addr add 127.0.0.1/8 brd + dev lo scope host
ip link set dev lo up

ip addr add 169.254.2.10/16 brd + dev eth0 scope global
ip link set dev eth0 up

ip route add default via 169.254.2.2

echo nameserver 169.254.2.3 >> /etc/resolv.conf

# Scan for MDs.
mdadm -As --auto=yes --run

# Scan for LVM.
mkdir -p /etc/lvm
echo -n >> /etc/lvm/lvm.conf
lvm vgscan --ignorelockingfailure
lvm vgchange -ay --ignorelockingfailure

# These are useful when debugging.
if grep -sq guestfs_verbose=1 /proc/cmdline; then
    ls -lR /dev
    head -n 1234 \
	/etc/resolv.conf \
	/proc/mounts \
	/proc/modules \
	/proc/cpuinfo \
	/proc/uptime \
	/proc/version \
	/proc/partitions
    for i in pvs vgs lvs
    do
        echo "# lvm $i:"
        lvm $i
    done
    ip a
    ip r
    date
    echo -n "clocksource: "
    cat /sys/devices/system/clocksource/clocksource0/current_clocksource
    echo "These commands might be called by guestfsd, but they were not available at buildtime:"
    echo "missing commands: $missing_commands"
    echo
fi

if ! grep -sq guestfs_rescue=1 /proc/cmdline; then
  # Run the daemon under valgrind if ./configure --enable-valgrind-daemon
  vg_channel=/dev/virtio-ports/org.libguestfs.valgrind
  if [ -w $vg_channel ]; then
    if [ -r /etc/guestfsd.suppressions ]; then
      suppressions="--suppressions=/etc/guestfsd.suppressions"
    fi
    exec 3>$vg_channel
    vg="valgrind --leak-check=full --log-fd=3 --error-exitcode=119 --max-stackframe=8388608 --child-silent-after-fork=yes $suppressions"
    echo "enabling valgrind: $vg"
  fi

  # The host will kill qemu abruptly if guestfsd shuts down normally
  $vg guestfsd

  # Otherwise we try to clean up gracefully. For example, this ensures that a
  # core dump generated by the guest daemon will be written to disk.
else
  # Use appliance in rescue mode, also used by the virt-rescue command.
  eval $(grep -Eo 'TERM=[^[:space:]]+' /proc/cmdline)
  PS1='><rescue> '
  console_kname=ttyS0
  if test -f /proc/consoles
  then
    console_major_minor="`sed 's@^.* @@;p;Q' < /proc/consoles `"
    console_dev="`find /sys/ -name dev -type f -print0 | xargs -0 --no-run-if-empty grep -m 1 -l ${console_major_minor}`"
    console_kname=${console_dev%/dev}
    console_kname=${console_kname##*/}
  fi
  export TERM PS1
  echo
  echo "------------------------------------------------------------"
  echo
  echo "Welcome to virt-rescue, the libguestfs rescue shell."
  echo
  echo "Note: The contents of / are the rescue appliance."
  echo "You have to mount the guest's partitions under /sysroot"
  echo "before you can examine them. A helper script for that exists:"
  echo "mount-rootfs-and-do-chroot.sh /dev/sda2"
  echo
  setctsid "/dev/${console_kname}" bash -i
  echo
  echo "virt-rescue: Syncing the disk now before exiting ..."
  echo
fi

echo "Leaving."
echo s > /proc/sysrq-trigger
echo b > /proc/sysrq-trigger
exit 0
